v144 · accessibility · demo

Tooltip Recipe

A complete accessible tooltip implementation using CSS anchor positioning for layout — with no aria-details. The correct pattern uses aria-describedby on the trigger and role="tooltip" on the tip, while CSS anchor-name / position-anchor / anchor() handle placement.

CSS Anchor Positioning is not supported in this browser. The tooltips below still show (fallback absolute positioning), but the anchor() CSS functions have no effect. Try Chrome 125+ for the full experience.

Feature detection

CSS anchor positioning: checking…

Live demo — 4 placement variants

Hover or focus each button to see the tooltip appear. Each uses a different anchor()-based placement: top, bottom, left, right.

Tooltip above
Tooltip below
Tooltip left
Tooltip right

The code

<!-- Correct: aria-describedby + role="tooltip" --> <button id="settings-btn" aria-describedby="settings-tip"> Settings </button> <div id="settings-tip" role="tooltip"> Opens settings panel </div> <!-- The tooltip is HIDDEN from AT by default; role="tooltip" makes it accessible when aria-describedby points to it. -->
/* 1. Name the anchor element */ #settings-btn { anchor-name: --settings-btn; } /* 2. Pin the tooltip to the anchor */ [role="tooltip"] { position: absolute; position-anchor: --settings-btn; /* Place above: bottom edge = anchor's top */ bottom: calc(anchor(top) + 0.4rem); left: anchor(center); translate: -50% 0; /* centre horizontally */ opacity: 0; transition: opacity 0.12s; } /* 3. Show on hover/focus */ #settings-btn:hover + [role="tooltip"], #settings-btn:focus-visible + [role="tooltip"] { opacity: 1; }
<!-- WRONG: aria-details is for supplementary long-form content, NOT for layout-linked tips --> <button id="settings-btn" aria-details="settings-tip"> Settings </button> <div id="settings-tip"> Opens settings panel </div> <!-- aria-details makes AT announce "has details — press alt-down to expand", which is wrong for a simple tooltip description. -->

see also