Every project eventually pulls in a positioning library — Floating UI, Popper, or a hand-rolled equivalent — to answer one question: where do I put this tooltip so it sits next to its button and flips when it hits the edge of the screen? As of 2026, the browser answers that question itself. CSS anchor positioning reached Baseline, sitting at roughly 91% global support across Chromium, Firefox, and Safari, which means you can ship it in most production contexts without a polyfill.
The whole feature is three properties and one at-rule. Once it clicks, a surprising amount of JavaScript disappears.
The three properties that do most of the work
You name an element as an anchor with anchor-name. You tell a positioned element which anchor to attach to with position-anchor. And you place it relative to that anchor with position-area, which works like a 3x3 grid around the anchor — top, bottom center, bottom span-right, and so on. No measuring, no scroll listeners, no getBoundingClientRect.
tooltip.html + CSS
<button class="trigger">Hover me</button>
<div class="tooltip" popover>I am tethered in pure CSS</div>
<style>
.trigger {
anchor-name: --trigger;
}
.tooltip {
position: absolute;
position-anchor: --trigger;
/* place it centered above the button */
position-area: top center;
margin-bottom: 6px;
}
</style>
That is a working tooltip. It follows the button when the layout changes, and because it is a real popover, it also gets top-layer rendering and light-dismiss for free — no z-index war, no outside-click handler.
Flipping at the edges
The reason positioning libraries exist is the hard case: the tooltip is above the button, but the button is at the top of the viewport, so it needs to flip below. That is @position-try. You define alternate positions, list them as fallbacks, and the browser picks the first one that fits.
flip.css — fallbacks when there is no room
@position-try --flip-to-bottom {
position-area: bottom center;
margin-top: 6px;
margin-bottom: 0;
}
.tooltip {
position: absolute;
position-anchor: --trigger;
position-area: top center;
margin-bottom: 6px;
/* if "top center" would overflow, try the bottom */
position-try-fallbacks: --flip-to-bottom;
}
This is the exact behavior you used to import a library for, expressed in a handful of declarative lines the browser resolves at layout time.
What about the last 9%
Support is strong but not total. The core — anchor() and position-anchor — works in Chrome 125+, Firefox 132+, and Safari 18.2+, while the @position-try flip behavior wants Safari 18.4 or newer. For a tooltip, the graceful degradation is fine: an unsupported browser simply gets a statically positioned element instead of a flipping one, which is a cosmetic downgrade, not a broken UI. If you need pixel-identical behavior everywhere, keep the library for now; if "good enough on older Safari" is acceptable, you can delete it today.
The bigger shift
Anchor positioning is part of a run of platform features — popover, the top layer, container queries, :has() — that are steadily reclaiming things we outsourced to JavaScript a decade ago. The win is not just fewer dependencies; it is that layout logic lives in the layout engine, runs at native speed, and cannot get out of sync with the DOM because it is the DOM. Reach for the native version first, and only pull in a library when you hit its specific edge.
