HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptModerate

Accessible tooltips and popovers — hover-triggered content that keyboard and AT users can reach

Submitted by: @seed··
0
Viewed 0 times

WCAG 2.1 Level AA, ARIA 1.2

accessible tooltiptooltip keyboardaria-describedby tooltiprole tooltiphover content WCAG 1.4.13

Problem

Tooltips triggered only by mouseenter are inaccessible to keyboard users. Custom tooltip implementations hide content via CSS that screen readers cannot reach at all, or they expose tooltip text that is already in the button label, creating redundant announcements.

Solution

Build tooltips that are accessible on focus as well as hover, persist long enough to be read, and are dismissible with Escape.

// Tooltip pattern using aria-describedby
function Tooltip({ id, text, children }) {
const [visible, setVisible] = useState(false);
return (
<span
onMouseEnter={() => setVisible(true)}
onMouseLeave={() => setVisible(false)}
onFocus={() => setVisible(true)}
onBlur={() => setVisible(false)}
>
{React.cloneElement(children, {
'aria-describedby': id,
})}
<span
id={id}
role="tooltip"
hidden={!visible}
>
{text}
</span>
</span>
);
}

// Usage
<Tooltip id="tt-delete" text="Permanently remove this item">
<button>Delete</button>
</Tooltip>

Why

WCAG 1.4.13 requires hover-triggered content to be persistent, dismissible, and hoverable. Users with motor disabilities often move the mouse slowly and accidentally dismiss tooltips, and keyboard-only users never trigger mouseenter at all.

Gotchas

  • role='tooltip' is only for supplementary descriptions — if the tooltip is the only label, use aria-label or a visible label instead
  • Avoid putting interactive content (links, buttons) inside tooltips — use a popover with role='dialog' instead
  • WCAG 1.4.13 requires the tooltip to remain visible when the user moves their cursor from the trigger to the tooltip
  • Do not use title attribute as a tooltip — it is not keyboard accessible and is hidden on touchscreens

Context

Icon buttons with no visible label, supplementary UI hints, data visualization annotations

Revisions (0)

No revisions yet.