Tooltip — accessibility
Keyboard
- The bubble opens on
focusand closes onblur(capture handlers on the wrapper), so a keyboard user gets the same information as a mouse user — this is the part most tooltip implementations miss and this one has. - The bubble itself is never focusable and never traps focus (
pointer-events: none). - Escape does not dismiss it; moving focus away does.
- The 80 ms delay applies to focus as well as hover.
ARIA
- The bubble carries
role="tooltip"and gets an id; the single child trigger is cloned witharia-describedbypointing at it, so the text is announced as the control's description, after its name. content={null}renders nothing at all — no empty bubble, no danglingaria-describedby.- The tooltip is a description, never the name: an icon-only control still needs its own
aria-label. - A disabled
<button>is not focusable in most browsers, so the explanation on a disabled action is reachable by pointer but not by Tab — a real limit of the pattern, not of this component.
Focus
- No focus style of its own; the trigger keeps whatever ring it has (foundation ring from
ds.css). - The bubble does not move focus and cannot steal it.
Contrast
Computed from packages/ui/src/tokens/tokens.css:
- White text on
--ink-900= 17.59:1 light, 14.53:1 dark (the bubble keeps its own inverted surface in both themes). - The bubble has no border; separation comes from the fill and
--shadow-pop. - Text is
var(--small)at weight 500 — small, but far above the AA minimum thanks to the inverted surface.
Known limits
- A disabled control cannot take keyboard focus, so its tooltip is pointer-only.
- No touch equivalent: on a phone there is no hover, and the bubble is not tappable.
- Only above/below placement; a trigger at the very top or bottom edge gets the flipped position, never a side one.
- The hide is immediate, so the bubble cannot be "reached" — deliberate, but it means the text must be short enough to read at a glance.
Source: docs/popover/tooltip.a11y.md · GitLab