adobe / adobe/react-spectrum

Tooltip renders unexpected visible border because `border-bottom-width: var(--h)` is emitted without a default `--h` value

Open
#10,037 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
15.9k
Forks
1.6k
Avg merge
3d 9m
Merged PRs (30d)
59

Description

### Provide a general summary of the issue here

`Tooltip` in `@react-spectrum/s2` appears to generate atomic CSS where border width consumer classes are emitted in normal mode, but the custom property setters that define those widths are only emitted inside `@media (forced-colors: active)`.

This causes the browser to compute a visible border in normal mode when `--h` is undefined.

Chrome
Image

Safari
Image

### 🤔 Expected Behavior?

If tooltip borders are only intended for `forced-colors`, no border-width consumer class should be emitted in normal mode unless the corresponding CSS variable has a safe default.

### 😯 Current Behavior

A tooltip renders with an unexpected visible bottom border.

In DevTools, the tooltip element has:

```css
border-bottom-width: var(--h);
```

but `--h` is not defined.

Chrome then computes `border-bottom-width` to the initial value `medium`, which shows up as `3px`.

## Source

In `src/Tooltip.tsx`, tooltip border is only defined for `forcedColors`:

```ts
borderWidth: {
forcedColors: 1
},
borderStyle: {
forcedColors: 'solid'
},
borderColor: {
forcedColors: 'transparent'
},
```

## Generated CSS

The built CSS includes always-on consumer classes like:

```css
._kJ8iPYd13 {
border-top-width: var(--_k);
}
.hXMFGYc13 {
border-bottom-width: var(--h);
}
```

But the variable setters are only emitted inside `forced-colors` rules:

```css
@media (forced-colors: active) {
._jlf13 {
border-style: solid;
}
.ilA13 {
border-color: #0000;
}
.-_k_-l_kb13 {
--_k: 1px;
}
.-h_-lhb13 {
--h: 1px;
}
}
```

Outside `forced-colors`, `--h` is undefined.

## Why this seems wrong

The width consumer class is active outside `forced-colors`, but its backing variable is not guaranteed to exist outside `forced-colors`.

That means the computed value becomes invalid and the browser falls back to the initial value for `border-bottom-width`, which produces a visible border.

### 💁 Possible Solution

## Possible fixes

1. Provide default values:

```ts
borderWidth: {
default: 0,
forcedColors: 1,
}
```

2. Only emit the border-width classes inside `forced-colors`.

3. Emit default setters like:

```css
--_k: 0px;
--h: 0px;
```

## Workaround

This removes the artifact locally:

```tsx

Tooltip text

```

### 🔦 Context

_No response_

### 🖥️ Steps to Reproduce

Simple use

### Version

1.3.1

### What browsers are you seeing the problem on?

Chrome

### If other, please specify.

React + Vite

### What operating system are you using?

MacOS

### 🧢 Your Company/Team

_No response_

### 🕷 Tracking Issue

_No response_

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.