Tooltip

A tooltip is a small text bubble that describes the control it is attached to. It supplements a visible label — it never replaces one. Keep it text-only and non-interactive: a tooltip holds a short hint, not links, buttons, or anything a user must reach. The trigger points at the bubble with aria-describedby, the bubble carries role="tooltip", and the hint appears on focus and on hover and disappears again when the user moves away or presses Esc.

Live demo

Tab to the button or hover it: the hint appears. Press Esc while it is focused to dismiss it, and move the pointer onto the bubble — it stays put (WCAG 1.4.13). The button keeps its own visible text label, so the tooltip only adds to it.

When to use

When to use a tooltip

  • To add a short, supplementary hint to a control that already has a visible, programmatic name — for example clarifying what a labelled “Settings” button does.
  • When the hint is purely descriptive text: a few words, no interactive content, nothing the user must scroll to or click.
  • On a control that can receive focus (a <button>, link, or form field), so keyboard users get the hint too — not just pointer users.

If you need rich, interactive, or dismissible-on-its-own content, reach for a popover or disclosure instead — not a tooltip.

Markup

Wrap a real, focusable trigger and its bubble in a .ewa-tooltip. Tie them together with a matching aria-describedby and id, give the bubble role="tooltip", and start it hidden. The script reveals it on focus and hover; the CSS reveals it on :focus-within / :hover so it still works with JavaScript off.

tooltip.html
<span class="ewa-tooltip">
  <button type="button" aria-describedby="settings-tip">Settings</button>
  <span role="tooltip" id="settings-tip" class="ewa-tooltip__bubble" hidden>
    Opens your account settings
  </span>
</span>

Keyboard interactions

Keyboard interactions for the tooltip pattern
Key / action Result Why it matters
Tab to the trigger The tooltip appears while the trigger holds focus. Keyboard users get the same hint pointer users get on hover.
Esc Hides the tooltip without moving focus off the trigger. WCAG 1.4.13 requires the content be dismissible without moving the pointer or focus. Focusing the trigger again re-shows it.
Move focus away (Tab / Shift+Tab) The tooltip hides as focus leaves the trigger. The hint is tied to its control, so it should not linger once you leave (supports 2.1.1 Keyboard — no pointer needed at any step).

ARIA roles, states, and properties

The wiring is deliberately small — two attributes do the work, and there is no expanded/collapsed state to manage because a tooltip is not a toggle.

ARIA contract for the tooltip pattern
Element Attribute Purpose
Trigger (e.g. <button>) aria-describedby="ID" Points at the id of the role="tooltip" element so the bubble is read as the trigger's description — after its name and role.
Bubble role="tooltip" Identifies the element as a tooltip to assistive technology. It contains only text — no focusable or interactive children.
Bubble hidden Keeps the bubble out of the page and the accessibility tree until the trigger is focused or hovered; the script and the CSS toggle it.
  • The trigger keeps its own accessible name (its visible text or an associated label). aria-describedby only adds a description on top.
  • Do not put role="tooltip" on the trigger, and do not use aria-expanded — a tooltip is not an expandable control.
  • Removing the bubble from the DOM, or marking it hidden, removes it from the description; the script uses hidden so aria-describedby can stay in place.

Common mistakes

Avoid these

  • Tooltip as the only label. If the control has no visible text and no associated label, a tooltip is not a substitute — the name disappears the moment the tooltip closes. Give the control a real name first, then describe it.
  • Interactive content inside. Links, buttons, or form fields in a tooltip can't be reached reliably: there is no focus path into a tooltip and it closes on blur. Use a popover or disclosure for anything actionable.
  • Not dismissible. A tooltip that won't go away on Esc can permanently cover content for low-vision and magnifier users — a direct failure of WCAG 1.4.13 Content on Hover or Focus.
  • Not hoverable. If the bubble vanishes the instant the pointer crosses from the trigger toward it, users can't read long hints or interact with what's underneath on their own terms — also a failure of WCAG 1.4.13. Keep it visible while the pointer is over the trigger or the bubble.