CSS anchor positioning: tooltips that position themselves
Positioning a tooltip next to its trigger sounds trivial and never was. The trigger scrolls, the container clips, the viewport edge looms—so we shipped JavaScript that measures rectangles on every frame and nudges an absolutely-positioned div around. Entire libraries existed for this one job.
Anchor positioning moves the job into layout itself. Any element can declare itself an anchor; any other element can position relative to it—across the DOM, regardless of containment.
The pattern
.trigger {
anchor-name: --menu-btn;
}
.tooltip {
position: fixed;
position-anchor: --menu-btn;
/* sit above the anchor, centered */
bottom: anchor(top);
justify-self: anchor-center;
/* and flip below if space runs out */
position-try-fallbacks: flip-block;
}The last line is the library-killer: position-try-fallbacks tells the browser what to do when the preferred position overflows. Tooltip near the top of the viewport? It flips underneath automatically—no resize observers, no scroll listeners, recalculated by the engine at layout speed.
“The browser always knew where both elements were. We just never had the syntax to introduce them.”
Better together
Combine it with the Popover API and the entire floating-UI category—menus, tooltips, selects, hover cards—becomes declarative: popover handles top-layer stacking and dismissal, anchor positioning handles geometry. Browser support has reached the green zone across modern engines, with a straightforward fallback: position statically, or keep the small JS shim for the long tail. The direction is unmistakable—another decade-old JavaScript tax, repealed.