CSS anchor positioning
Tether tooltips, menus, and popovers to the element that triggers them with pure CSS — no JavaScript positioning library, and it works across overflow and stacking boundaries.
What it is
CSS anchor positioning lets one element be positioned relative to another — its anchor — without the two sharing a parent or a containing block. You name an anchor, associate a positioned element with it, and place that element against the anchor’s edges using CSS alone.
Three pieces do the work:
anchor-name: --triggerregisters an element as a named anchor.position-anchor: --triggeron an absolutely (or fixed) positioned element associates it with that anchor.- The
anchor()function and theposition-areaproperty place the element against the anchor’s edges.
.trigger {
anchor-name: --trigger;
}
.tooltip {
position: absolute;
position-anchor: --trigger;
position-area: top center; /* sit above, centred on the anchor */
margin-bottom: 0.5rem;
}
anchor-size() sizes an element from its anchor’s dimensions (a dropdown panel as wide as its button), and @position-try plus position-try-fallbacks let the element flip to a different side when it would overflow the viewport.
Why it matters
- No JavaScript positioning library. Tooltips, menus, comboboxes, and popovers have historically needed scripts (or Popper/Floating UI) to measure the trigger and reposition on scroll and resize. The browser now does this natively, every frame.
- It crosses boundaries. Anchor positioning works regardless of
overflow: hiddenancestors,z-index, ortransformcontaining blocks — the same constraints that break hand-rolled overlays. It pairs naturally with the Popover API and top-layer elements. - Viewport-aware by default.
@position-trygives you fallback positions, so an overlay that would clip off-screen flips to a side that fits — behaviour you previously wrote and maintained by hand.
How to implement
Use it to position non-blocking UI relative to its trigger. Treat it as progressive enhancement: give the element a sensible static position first, then layer anchor positioning on top.
@supports (anchor-name: --x) {
.menu {
position: absolute;
position-anchor: --menu-button;
position-area: bottom span-right;
position-try-fallbacks: flip-block, flip-inline;
}
}
position-try-fallbacks lists alternatives the browser tries in order until the element fits. position-visibility: anchors-visible hides the element when its anchor scrolls out of view, so a detached tooltip does not linger.
Common mistakes
- Forgetting to position the element.
position-anchorandanchor()only apply to an element withposition: absoluteorfixed. Without it, nothing moves. - No fallbacks. An anchored element with a single fixed side will overflow the viewport near screen edges. Provide
position-try-fallbacks. - Making it the only mechanism. Until anchor positioning is universally available, keep a usable static fallback for browsers without support rather than leaving the overlay unpositioned.
- Anchoring across documents. Anchor and anchored element must be in the same document and not separated by certain layout containers — check the association actually resolves.
Verification
@supports (anchor-name: --x)gates the enhancement; confirm the fallback layout is acceptable on its own.- In DevTools, inspect the anchored element and confirm its inset values resolve against the anchor.
- Scroll and resize the viewport: the element should follow its anchor and flip via fallbacks rather than clipping.
- Baseline: CSS anchor positioning became newly available across browsers in early 2026 — verify your target support before relying on it without a fallback.
Related topics
Sources & further reading
- CSS Anchor Positioning Module Level 1 — W3C CSS Working Group
- MDN — Using CSS anchor positioning — MDN
- MDN — anchor-name — MDN
- Introducing the CSS anchor positioning API — Chrome for Developers