CSS Anchor Positioning

Tether one element's position and size to another element declaratively — tooltips, popovers, menus, error messages, and "magnetic" highlights — replacing the JavaScript measuring loops (Popper, Floating UI) that historically did this.

Anchor positioning lets any element be named an anchor and any absolutely/fixed-positioned element bind to it. The positioned element then reads the anchor's edges and size at layout time, so it stays tethered as the anchor scrolls, resizes, or animates — with no getBoundingClientRect loop on the main thread. Source: MDN, https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_anchor_positioning/Using, 2026-06-12

Association: name the anchor, bind the target

.anchor   { anchor-name: --a; }          /* declare an anchor */
.tooltip  { position: fixed;             /* must be absolute/fixed */
            position-anchor: --a; }       /* bind to the anchor */

The Popover API creates an implicit anchor reference when a popover is associated with its invoker via popovertarget/commandfor, so popovers and customizable <select> pickers get anchoring for free. Use anchor-scope to stop repeated components from all binding to the last anchor on the page. Source: MDN, 2026-06-12

Placement: three mechanisms

Mechanism What it does Example
anchor() on inset props Pin an edge to the anchor's edge; composes inside calc() top: calc(anchor(bottom) + 5px)
position-area Drop the element into a 3×3 grid around the anchor position-area: top span-left
anchor-center Center on the anchor via justify-self/align-self justify-self: anchor-center

anchor-size() sizes the target from the anchor's dimensions: width: anchor-size(width) or inline-size: calc(anchor-size(self-inline) * 4). Source: MDN, 2026-06-12

Magnetic nav highlight (no JS)

The bookmarked recipe from Jhey Tompkins moves the anchor-name onto whichever <li> is hovered with :has(), then a single ::before pill reads the anchor's geometry and CSS transitions glide it between items:

li:has(a:is(:hover, :focus-visible)) { anchor-name: --a; }
ul::before {
  position-anchor: --a;
  left:   anchor(left);
  top:    anchor(top);
  width:  anchor-size(width);
  height: anchor-size(height);
  transition: 0.2s; /* the magnetic glide */
}

One pseudo-element follows the active link — the entire interaction is declarative CSS. Source: X/@jh3yy, 2026-05-04 (1,553 likes, 1,804 bookmarks). Collected with Jhey's other recipes in Jhey CSS Techniques.

The reviewed video contact sheet shows the same highlight pill following horizontal and vertical menu layouts. That is the reusable point: the active geometry is owned by layout, so the effect survives orientation changes without a JavaScript measuring loop.

Overflow fallbacks and conditional hiding

The module also solves the "tooltip flips offscreen" problem in CSS: declare alternate placements with @position-try / position-try-fallbacks and the browser picks the first that fits. position-visibility hides the positioned element when its anchor scrolls out of view. This is the part that previously required Floating UI's flip/shift middleware. Source: MDN, 2026-06-12

Browser support — enhancement only

Engine Status (2026)
Chromium (Chrome/Edge) Shipped 125+ (2024)
Safari, Firefox In progress — not yet stable

Not Baseline yet. Treat as progressive enhancement and gate it: @supports (anchor-name: --x) { … }, with a sane static fallback (Floating UI or simple position: absolute) for engines that lack it. Pairs naturally with the Popover API and <dialog>. Source: MDN, 2026-06-12


Timeline