Others

Tooltip

Available

Supplementary text that appears on focus or hover. Uses aria-describedby with keyboard support.

Specification updated

Specification changes under review

What Is a Tooltip?

A tooltip is a small popup that appears when an element receives focus or hover, providing supplementary description for that element. They are commonly used to explain icon buttons or add hints to input fields.

An important caveat: tooltips are "supplementary," not primary information. Essential information required for an operation should never be placed only in a tooltip.

Why Does Accessibility Matter?

Custom tooltips or relying on the title attribute cause the following problems:

The solution is to associate the tooltip with aria-describedby, show it on both focus and hover, and allow dismissal with Esc.

Live Demo (Recommended Implementation)

The button below has an APG-compliant tooltip. Verify that it appears not only on mouse hover but also when focused with Tab, and can be dismissed with Esc.

Accessible Tooltip

Try it: Tab to focus the button and the tooltip appears → Esc to dismiss → Hover with mouse and it appears again. The tooltip itself does not receive focus.

Tip

When a screen reader focuses the button, it announces something like "Save, button, Saves your changes to the server" — the name followed by the description. This is the effect of aria-describedby.

Keyboard Interaction

KeyActionPriority
TabFocus on the trigger displays the tooltipRequired
EscDismiss the visible tooltip (focus remains on the trigger)Required

Note

The tooltip itself does not receive focus (it is not a Tab target). Since it's merely supplementary to the trigger, avoid placing links or buttons inside it (if you need interactive content, use a popover or dialog instead).

Required WAI-ARIA Roles & Properties

TargetAttribute / RoleMeaning
Triggeraria-describedby="<tooltip id>"Associates the tooltip as a description. Read aloud when the trigger receives focus.
Tooltip elementrole="tooltip"Identifies the element as a tooltip.
Tooltip elementhidden (when not visible)Excludes it from screen readers and rendering while hidden.
TriggerFocusable element (e.g. <button>)Ensures keyboard accessibility. Do not use <div> or similar.

Recommended Pattern (Good)

Good / Recommended

Associate with aria-describedby, show on both focus and hover, and dismiss with Esc.

Markup:

<!-- The trigger must be a focusable element (e.g. button) -->
<button type="button"
        id="tip-trigger"
        aria-describedby="tip-text">
  Save
</button>

<!-- The tooltip itself. Not focusable, role="tooltip" -->
<div id="tip-text" role="tooltip" hidden>
  Saves your changes to the server
</div>

Show/hide script (supporting both focus and hover + Esc is the key):

const trigger = document.getElementById('tip-trigger');
const tip = document.getElementById('tip-text');

if (trigger && tip) {
  const show = () => { tip.hidden = false; };
  const hide = () => { tip.hidden = true; };

  // Must show on both focus and hover
  trigger.addEventListener('focus', show);
  trigger.addEventListener('blur', hide);
  trigger.addEventListener('mouseenter', show);
  trigger.addEventListener('mouseleave', hide);

  // Allow dismissing with Esc
  trigger.addEventListener('keydown', (e) => {
    if (e.key === 'Escape') hide();
  });
}

Note

As a note, tooltip content should be kept to "nice-to-have" supplementary information.Information essential for operation should be written directly in the label or body text. The displayed tooltip should be dismissible with Esc and should not disappear when the mouse moves over it (WCAG 1.4.13).

Anti-Pattern (Bad)

The buttons below rely on the title attribute only, or use a hover-only custom tooltip. Focusing with Tab shows no description, and Esc doesn't dismiss anything.

title-only / hover-only tooltip
Saves your changes

Try it: Tab to focus shows no description (left: title doesn't appear on keyboard focus / right: hover-only). Neither works on touch devices, and Esc has no effect.

<!-- ❌ Anti-pattern 1: title attribute only -->
<button type="button" title="Saves your changes">Save</button>

<!-- ❌ Anti-pattern 2: hover-only custom tooltip -->
<span class="has-tip">Save
  <span class="tip">Saves your changes</span>
</span>

Bad / Avoid

Problems with this implementation:

  • Doesn't appear on keyboard focus — Neither title nor hover-only CSS shows on Tab focus.
  • Doesn't appear on touch — On devices without hover, the tooltip never displays.
  • No association — Without aria-describedby, the description and trigger are not linked.
  • Can't be dismissed — No mechanism to close with Esc (WCAG 1.4.13 violation).

Tip

The title attribute is "better than nothing," but it displays slowly, can't be styled, and doesn't appear on keyboard focus. If you want to properly show supplementary descriptions, implement them with aria-describedby + custom show/hide logic.

Implementation Checklist

Field Notes — Where practice diverges from the APG

Treating tooltips as visual-only hints — no role="tooltip", no aria-describedby

The APG says
The tooltip element should have role="tooltip" and be referenced from the trigger via aria-describedby, appearing on both hover and focus and dismissible with Escape. Touch input is not addressed at all.
What practice does
Base UI's Tooltip sets neither role="tooltip" nor aria-describedby; its docs state tooltips are visual aids and essential information belongs directly on the trigger (e.g. aria-label). Tooltips are disabled on touch devices, with Popover (openOnHover) recommended for essential content. Material UI guards against accidental touch triggering with enterTouchDelay (700ms long-press by default).
Why
Tooltips are designed around hover and focus — neither exists on touch devices, where a tap activates immediately. Information that lives only in a tooltip is structurally unreachable for some users. Sarah Higley flagged this incompatibility in 2019 and the spec side has not resolved it; Radix, which follows the APG faithfully, keeps receiving "tooltip does not open on touch" issues. Base UI codified a decision rule — is the trigger's purpose the open/close itself? — and confines tooltips to redundant visual hints.

Adopted by:Base UIMaterial UI

Sources:Base UI — Tooltip(Accessibility guidelines)(opens in a new tab)Sarah Higley — Tooltips in the time of WCAG 2.1(opens in a new tab)MUI — Tooltip(opens in a new tab)

Ariakit defaults to aria-labelledby instead of aria-describedby

The APG says
The trigger references the tooltip via aria-describedby — the tooltip is supplementary description, not the source of the accessible name.
What practice does
Ariakit v2 changed the default association to aria-labelledby. Consumers opt in to aria-describedby only when the tooltip is genuinely a description.
Why
In the wild, tooltips overwhelmingly label icon-only buttons that have no other accessible name. With aria-describedby such a button has no name at all; the maintainer verified inconsistent announcements across screen readers (VoiceOver duplicating "Undo, button, Undo" versus NVDA). aria-labelledby announces consistently, so Ariakit chose real-world usage over the APG default — while openly acknowledging the divergence and the remaining debate about dropping role="tooltip" entirely.

Adopted by:Ariakit

Sources:Ariakit — Tooltip(opens in a new tab)ariakit/ariakit#2228 — Tooltip accessibility(opens in a new tab)

The APG tooltip pattern itself lacks consensus — the field reaches for toggletips

The APG says
The APG tooltip pattern is explicitly marked "work in progress" without task force consensus — unresolved since 2016. The click-toggled "toggletip" does not exist in the APG pattern list at all.
What practice does
Sarah Higley calls role="tooltip" the "unloved child of roles" and recommends tooltips only for non-essential supplements. Heydon Pickering proposes the toggletip — a click-toggled info box that works across touch, mouse, and keyboard — as the replacement.
Why
Beyond the structural hover/focus flaw, WCAG 2.1's 1.4.13 (Content on Hover or Focus) added dismissable / hoverable / persistent requirements that sharply raised the cost of an APG-style tooltip. The W3C ARIA WG itself has acknowledged in issues and TPAC 2023 discussions that the current tooltip role cannot express rich-content use cases and needs rework. Toggletips draw their own criticism — essential information should not hide behind a tiny button — so they are a leading alternative, not a settled consensus.

Adopted by:Sarah HigleyHeydon Pickering (Inclusive Components)

Sources:Sarah Higley — Tooltips in the time of WCAG 2.1(opens in a new tab)Inclusive Components — Tooltips & Toggletips(opens in a new tab)w3c/aria-practices#128 — Tooltip pattern consensus(opens in a new tab)


Source (English):Tooltip Pattern — W3C APG(opens in a new tab)