Tooltip
A small floating bubble that describes the element it’s placed inside. Render
<Tooltip> as a child of the element it annotates — it doesn’t affect that
element’s layout, and its content can be anything.
It shows on hover (after a short delay) and on keyboard focus, and dismisses
on mouse leave, blur, Esc, or when the anchor scrolls away. On touch
devices — where there’s no hover and a tap shouldn’t surface it — it opens on
press-and-hold and lingers briefly after you lift, so it stays readable. By
default the bubble follows the cursor; pass static to pin it under the anchor,
or interactive to make it hoverable and clickable (for content like links).
// Place <Tooltip> inside the element it describes. Hover or focus the anchor.<Button label="Save"> <Tooltip>Saves your work</Tooltip></Button>
// Pin above the anchor instead of following the cursor.<span style={{ cursor: 'help' }}> Status <Tooltip placement="top" static>Last checked 2 minutes ago</Tooltip></span>
// A near-instant tooltip on a keyboard-focusable button. Never use delay={0} — use ~50.<Button priority="tertiary" underline="dashed" label="Focus me with the keyboard"> <Tooltip delay={50} static>Shows on focus, dismiss with Esc</Tooltip></Button>
// Rich content — render anything.<Button icon="info"> <Tooltip placement="top"> <strong>Heads up</strong> — this action can't be undone </Tooltip></Button>
// Interactive: the bubble becomes hoverable + clickable, so its content// (links, buttons) works. `interactive` implies `static` (pinned) — a bubble// that follows the cursor can't be entered. Move from the anchor into the// bubble to click; press Esc to dismiss.<Button label="Interact"> <Tooltip interactive placement="top"> See the <a href="/guide">full guide</a> for details </Tooltip></Button>The underlying <a-tooltip> works in plain HTML too, as a child of any element:
<button> Save <a-tooltip>Saves your work</a-tooltip></button>Adjacent and nested tooltips
Only one tooltip shows at a time. Moving between adjacent anchors hands off cleanly — the outgoing bubble lingers briefly and keeps following the cursor, then the next one cross-fades in (no blink). With nested anchors, the inner (descendant) tooltip wins while you’re over it, and the outer takes back over when you leave. Hover the examples to feel it.
// Adjacent — moving from one to the next cross-fades, no blink.<Button label="First"><Tooltip>First tooltip</Tooltip></Button><Button label="Second"><Tooltip>Second tooltip</Tooltip></Button>
// Nested — wrap stray text in a <span> so the tooltip stays a direct child of// the box (its anchor). The inner tooltip wins while you're over the inner button.<div tabIndex={0}> <span>Outer box</span> <Tooltip>Outer tooltip</Tooltip> <Button label="Inner button"><Tooltip>Inner tooltip</Tooltip></Button></div>Playground
A single tooltip on a button — tweak its props (or edit the code) and hover the
button. The props panel is generated from the Tooltip API and edits the
<Tooltip> element, not the <Button> it’s attached to.
Component props
| Prop | Type | Default | Description |
|---|---|---|---|
| children? | ReactNode | — | Tooltip content. Renders anything — text, markup, an icon + text. Lives in the light DOM, so it's styleable with your own plain CSS. |
| delay? | number | 250 | Show delay in milliseconds after hover / focus. Never use 0 — use
~`50` for a near-instant tooltip (0 has caused issues in practice). |
| interactive? | boolean | — | Make the bubble hoverable and clickable — enables pointer events and
keeps it open while the cursor is over it, so its content (links,
buttons) can be interacted with. Implies static (an interactive
bubble can't follow the cursor). |
| placement? | bottomtop | bottom | Which side of the anchor the bubble prefers. Auto-flips to the other side when there isn't room. |
| static? | boolean | — | Pin the bubble under the anchor instead of following the cursor. |
Inherited props (className, id, style, tabIndex, title)
| Prop | Type | Default | Description |
|---|---|---|---|
| className? | string | — | CSS class name. Merged with any internal classes by the component. |
| id? | string | — | HTML id attribute. |
| style? | CSSProperties | — | Inline styles applied to the root element. |
| tabIndex? | number | — | Tab order. Set to -1 to skip the element when tabbing. |
| title? | string | — | HTML title attribute — native browser tooltip on hover. |
Component tokens
Tooltip exposes only the box “chrome” that lives inside the shadow popover and is therefore impossible to reach with plain consumer CSS. Every token below is a (shadow-only API) — override it in consumer CSS to restyle a single instance.
The bubble’s content is slotted light DOM, but the bubble gives it a
normalized text baseline (Anta body typography: --text-3 colour, wdth 100,
0.02ch letter-spacing, 1.5 line-height) so it does not inherit the
anchor’s text styling — e.g. a <Button>’s condensed width axis or tighter
letter-spacing won’t bleed into the tooltip. To customise one tooltip’s text,
put a class on the content you pass to <Tooltip> and style it directly — a rule
that targets the content wins over the inherited baseline:
/* applied to your own element inside <Tooltip> */.tip-rich { font-size: 15px; font-weight: 600; letter-spacing: normal; }| Token | Description |
|---|---|
--tooltip-bg | Bubble background — a frosted translucent surface. Defaults to color-mix(in oklch, var(--bg-1) 80%, transparent), paired with the bubble’s backdrop-filter: blur(8px) (alpha lowered in dark mode). |
--tooltip-shadow | Bubble drop shadow. Has a distinct light-mode and dark-mode recipe. |
--tooltip-radius | Corner radius. Defaults to 3px. |
--tooltip-max-width | Maximum width before content wraps. Defaults to min(calc(100vw - 20px), 80ch). |
--tooltip-border | Bubble border. Defaults to none — the hairline edge comes from --tooltip-shadow. Set e.g. 1px solid var(--border-5) for a real border. |
--tooltip-backdrop-filter | Backdrop filter behind the bubble (the frost). Defaults to blur(8px). Set to none (with --tooltip-bg: transparent) for a fully see-through bubble. |