CSS Anchor Tooltip Pro
Tooltips attached to their button with CSS Anchor Positioning: they switch sides at the window edge, close with Escape and stay readable everywhere.
Updated
This effect is part of Effect.Labs — 840 vanilla effects, some free, some premium. Utilities has 43 effects, including 3 free. Explore the category →
3 usage examples



How it works
Each .atp-btn button is followed by its .atp-tip tooltip inside an .atp-pair that sets the wanted direction: atp-top, atp-bottom, atp-left or atp-right. The tooltip shows when the button or the tooltip itself is hovered, and on keyboard focus (:focus-visible), with a 0.18 s fade; hidden, it is visibility: hidden.
When the browser knows CSS Anchor Positioning, the script gives each button a unique anchor name (anchor-name) and ties it to its tooltip (position-anchor). The tooltip then switches to position: fixed with position-area: it follows its button anywhere on the page and, if the window lacks room on that side, position-try-fallbacks flips it to the other (top ↔ bottom, left ↔ right). On each opening, the script records the actual side in data-atp-side to put the small arrow on the right side.
Without Anchor Positioning (older browsers) or without JavaScript, the same tooltip is placed with position: absolute around its button, on the intended side, with no flipping. Escape closes the open tooltip without moving the mouse or the focus; it comes back once you leave the button and return.
Accessibility
- Tied to its button: the script gives each tooltip a unique id and sets it in the button's
aria-describedby. The screen reader reads the button name, then its description. - Truly hidden at rest:
visibility: hiddentakes closed tooltips out of reading; the description stays available througharia-describedby. - Dismissible and hoverable (WCAG 1.4.13): Escape closes it; the mouse can move from the button onto the tooltip to read or select its text without it vanishing.
- Reduced motion: under
prefers-reduced-motion: reduce, the 4 px slide goes away, leaving a plain fade. - Touch: tapping the button shows the tooltip (hover emulated by the browser), tapping elsewhere usually closes it. Do not put essential information only in a tooltip: on mobile it stays easy to miss.
Browser compatibility
CSS Anchor Positioning (anchor-name, position-area, position-try-fallbacks): Chrome 129, Firefox 147, Safari 26; before that, automatic fallback to simple placement. Maximum width in container units (cqw): Chrome 105, Firefox 110, Safari 16. About 2 KB of JavaScript for the anchor names, aria-describedby, Escape and the arrow. Measured in Chromium 151, Firefox 153 and WebKit 26.5 (Playwright): 4 directions in 2 copies, flipping at the window edges, forced fallback without Anchor Positioning, Escape on hover and on focus, mouse moving onto the tooltip, code pasted twice, touch, 390 px, reduced motion, 0 errors.
Without Anchor Positioning or without JavaScript, the tooltip stays on its intended side even near an edge, where it may overflow. Without JavaScript there is no aria-describedby and no closing with Escape.
The code
HTML structure to paste into your page (the CSS + JS come with your purchase):
<div class="fx-0787-root">
<div class="atp-demo">
<div class="atp-pair atp-bottom">
<button class="atp-btn" type="button">Bottom</button>
<p class="atp-tip" role="tooltip">Below the button…</p>
</div>
<div class="atp-pair atp-right">…</div>
<div class="atp-pair atp-left">…</div>
<div class="atp-pair atp-top">…</div>
</div>
</div>
One-time payment, no subscription — the code is yours forever
Customize
Options passed to the API or data-* attributes:
| Option / property | Default | Effect |
|---|---|---|
Direction (HTML — class of .atp-pair) |
atp-top, atp-bottom, atp-left, atp-right |
The tooltip's preferred side; it moves to the opposite side when the window lacks room (with Anchor Positioning). |
Colours (CSS — --tip-bg, --tip-fg) |
#6d5efc and #fff |
Background and text of the tooltip and its arrow; set on the root or on a single pair. |
Gap (CSS — --tip-offset) |
10px |
Distance between button and tooltip. Above 14 px, moving the mouse onto the tooltip becomes less reliable. |
Maximum width (CSS — --tip-width) |
min(220px, 44cqw) |
Beyond it the text wraps. Add white-space: nowrap for short single-line labels. |
Cross demo (HTML/CSS — .atp-demo) |
4 buttons around an empty centre | Drop this container in your page: pairs work anywhere inside the root. |
FAQ
aria-describedby. Only the flip near an edge is missing: close to the window edge, the tooltip may then overflow.position: fixed and placed against the window, so a parent that clips its content does not cut it (unless that parent has a transform or a filter). In fallback mode it is position: absolute and may be clipped.role="tooltip") only holds text, and focus cannot be moved into it. For links or buttons, use a popup opened on click.