Try it
Drag with a pointer, or move with the arrow keys when focused.
I follow the anchor. No script moves me.
Support: checking…
Anchor:
—
Tooltip: —
Active side: —
Drag the button or the tooltip near an edge with auto-flip on and watch the tooltip flip sides by itself. Scroll this page or resize the window: it stays glued. The button also moves with arrow keys when focused. The script below only moves the anchor; the tooltip's position is computed entirely by CSS.
Why not just JavaScript?
The old way works, but you own every edge case: measuring, scroll, resize, zoom, and the flip math when the tooltip would overflow. Anchor positioning hands all of that to the browser.
The old way JS you maintain
function placeTip() {
const a = anchor.getBoundingClientRect();
const t = tip.getBoundingClientRect();
let top = a.bottom + 10;
let left = a.left + a.width / 2 - t.width / 2;
// flip when overflowing, by hand
if (top + t.height > innerHeight)
top = a.top - t.height - 10;
if (left < 0) left = 8;
if (left + t.width > innerWidth)
left = innerWidth - t.width - 8;
tip.style.transform =
`translate(${left}px, ${top}px)`;
}
addEventListener('scroll', placeTip,
{ passive: true });
addEventListener('resize', placeTip);
new ResizeObserver(placeTip)
.observe(document.body);
placeTip();
Anchor positioning the browser owns it
#anchor { anchor-name: --tip; }
#tip {
position: absolute;
position-anchor: --tip;
/* margin would not flip; bake the gap into the inset */
top: calc(anchor(bottom) + 10px);
left: anchor(center);
translate: -50% 0;
/* flip automatically near edges */
position-try-fallbacks:
flip-block, flip-inline;
}
The flip is the part people underestimate. Hand-rolled flip logic breaks on zoom, on nested scrollers, and on rapid resizes.
position-try-fallbacks: flip-block, flip-inline re-runs inside the browser's layout pass, so it can never go stale.
Honest notes
- Support: Chrome/Edge 125+, Safari 26+, Firefox 147+. The core (
anchor-name,position-anchor,anchor(),position-try-fallbacks) is Baseline 2026. Your browser: checking… - Guard it anyway. Wrap anchor styles in
@supports (anchor-name: --a)and ship a static fallback (e.g. the tooltip hidden, or plainly placed) for older browsers. - Sub-features diverge. Newer pieces like
position-visibility: anchor-visibleandposition-anchor: normalare still rolling out per engine. The core shown here is the safe set. - JavaScript still wins when the anchor isn't in the DOM (virtual lists) or lives in a different shadow tree. For everything else, this is the default I'd reach for over a positioning library.
One gotcha: the anchor and the positioned element must be in the same shadow tree, and the positioned element needs
position: absolute (or fixed). Also note this demo uses explicit anchor() insets rather than the position-area shorthand: same result, wider support (the shorthand was renamed from inset-area mid-rollout).