Articles

CSS Anchor Positioning Explained

CSS anchor positioning lets an element attach to another element's edges without JavaScript. How anchor(), position-anchor, and fallbacks work.

Takina Takina · · 4 min read
A close-up of CSS code on a screen

CSS anchor positioning is a set of properties that let you tether one element to the edges of another — a tooltip to its trigger button, a dropdown to its menu handle — without measuring positions in JavaScript. You name an element as an anchor, reference it from a positioned element with the anchor() function, and the browser keeps them aligned as the page scrolls or resizes.

The problem it replaces

Popovers, tooltips, dropdowns, and comboboxes all share the same layout problem: some floating element needs to sit next to a trigger element, tracking its position. Historically, solving this meant JavaScript — libraries like Popper.js exist almost entirely to compute top/left coordinates by reading getBoundingClientRect() on scroll and resize, then writing inline styles back. That’s extra JavaScript, extra reflows, and a layout that only updates as fast as your event listeners fire.

Anchor positioning moves that computation into the browser’s layout engine, the same place position: absolute and CSS Grid already live. The browser knows where the anchor is on every layout pass, so the tethered element stays aligned for free.

The core mechanism

An anchor is any element given a name via the anchor-name property:

.trigger {
  anchor-name: --my-anchor;
}

A separate element then positions itself relative to that anchor by combining position: absolute (or fixed) with the anchor() function inside its position properties:

.tooltip {
  position: absolute;
  position-anchor: --my-anchor;
  top: anchor(bottom);
  left: anchor(left);
}

anchor(bottom) resolves to the anchor’s bottom edge; anchor(left), anchor(right), anchor(top), and anchor(center) work the same way for their respective edges. The positioned element no longer needs to share a parent with its anchor in the DOM — a longstanding limitation of plain position: absolute, which only positions relative to the nearest positioned ancestor.

Handling overflow with position-try

A tooltip anchored below a button near the bottom of the viewport will overflow off-screen. Anchor positioning addresses this with position-try-fallbacks, which lets you list alternate positions the browser should try if the preferred one would overflow:

.tooltip {
  position-try-fallbacks: flip-block, flip-inline;
}

flip-block flips the element to the opposite side along the block axis (e.g., from below the anchor to above it); flip-inline does the same along the inline axis. The browser evaluates these automatically during layout — no scroll listener recalculating whether the tooltip is about to clip.

How it composes with the rest of the positioning toolkit

Anchor positioning doesn’t replace position: absolute — it extends it. You still need position: absolute or fixed set on the element; position-anchor and anchor() just give you a new coordinate reference other than the containing block. It also composes naturally with the popover mechanism in HTML, since popovers already float outside normal document flow and commonly need to be tethered to a trigger.

It’s worth contrasting with other CSS features that solve adjacent “where does this go” problems. Container queries let an element respond to its container’s size; anchor positioning lets an element respond to another element’s position. Subgrid aligns nested grid items to a parent’s tracks; anchor positioning aligns arbitrary elements that aren’t in a grid relationship at all. And where the CSS box model determines how an element occupies space, anchor positioning determines where that space is placed relative to a completely different element in the tree.

Anchor positioning vs. JavaScript-based positioning

CSS anchor positioningJS positioning libraries
Recalculates on scroll/resizeAutomatically, as part of layoutRequires event listeners
DOM relationship requiredNone — anchor and target can be anywhereNone (same advantage)
Overflow handlingDeclarative via position-try-fallbacksManual collision detection logic
Extra JavaScript bundleNoneA dependency, however small
Runtime costHandled by the layout engineRuns on the main thread per event

Where it fits today

Anchor positioning is a newer CSS capability, so treat it the way you’d treat any progressive enhancement: build the tooltip or dropdown so it degrades acceptably without it, and layer in anchor() and position-try-fallbacks for browsers that support them. It pairs well with feature-detection patterns similar to those used for other modern CSS additions like :has() or cascade layers — ship a reasonable fallback, then enhance.

The takeaway

Anchor positioning gives CSS a native answer to a problem JavaScript libraries have solved for years: keeping one element tethered to another’s edges. anchor-name marks the reference element, anchor() reads its edges from anywhere in the positioning stack, and position-try-fallbacks handles the overflow cases that used to require manual collision detection. For tooltips, popovers, and dropdowns, it’s a meaningful chunk of JavaScript you can simply delete.

Takina Takina · · 4 min read

CSS object-fit and object-position, Explained

object-fit controls how an image or video is cropped inside its box, and object-position controls which part of it stays visible. How they work together.

#CSS #Web Development #Frontend
Takina Takina · · 5 min read

CSS inherit, initial, unset & revert Explained

CSS's four global keywords control where a property's value comes from. How inherit, initial, unset, and revert differ, with a comparison table.

#CSS #Web Development #Frontend
Takina Takina · · 4 min read

Dynamic Viewport Units: dvh, svh, and lvh Explained

dvh, svh, and lvh fix the classic mobile vh bug where browser toolbars cut off full-height layouts. Here's what each unit measures and when to use it.

#CSS #Web Development #Frontend