Anchor Positioning: What the Spec Doesn't Tell You
Anchor positioning shipped fast. The first draft of the spec landed in June 2023, and Chrome 125 shipped support just a year later. Compare that with custom properties, which took four years from first draft to implementation. That speed is exciting, but it leaves less room for the CSS Working Group to polish drafts before browsers ship them. Once a feature is in browsers, it's hard to change. As a result, anchor positioning has some quirks worth knowing about.
The Inset-Modified Containing Block
For absolutely positioned elements, the containing block is normally the viewport or the nearest ancestor with a non-static position. Anchor positioning introduces a more subtle concept: the inset-modified containing block (IMCB). The spec defines it as the rectangle that results when inset properties like top, left, bottom, and right shrink the containing block.
.absolute {
position: absolute;
top: 80px;
right: 120px;
bottom: 180px;
left: 90px;
}
In that example, the element's containing block spans the viewport, but the IMCB is inset by 80px from the top, 120px from the right, 180px from the bottom, and 90px from the left.
The IMCB isn't essential for day-to-day CSS, but it matters for anchor positioning. Both position-area and position-try-order depend on it. The position-area property divides a target's containing block into an imaginary 3×3 grid using four lines:
- The start of the target's containing block.
- The start of the anchor element, or
anchor(start). - The end of the anchor element, or
anchor(end). - The end of the target's containing block.

With two elements attached via anchor positioning, you can place the target inside that grid:
.anchor {
anchor-name: --my-anchor;
height: 50px;
width: 50px;
}
.target {
position: absolute;
position-anchor: --my-anchor;
height: 50px;
width: 50px;
}
.target {
position: absolute;
position-anchor: --my-anchor;
position-area: top left;
height: 50px;
width: 50px;
}
Setting the target's dimensions to 100% shows that the IMCB shrinks to fill the selected grid region.
position-try-order also uses the IMCB's dimensions to rank the fallbacks in position-try-fallbacks. With the most-height or most-width values, the browser picks the fallback that grants the largest IMCB height or width.
Where the Spec and Browsers Diverge
Chromium-based browsers shipped several anchor positioning features early, then the spec changed. If your code works in one browser but not another, the mismatch between spec and implementation is often the culprit.
position-area
The inset-area property was renamed to position-area (#10209). The old name is supported until Chrome 131.
position-try-fallbacks
position-try-options was renamed to position-try-fallbacks (#10395).
inset-area() wrapper
The inset-area() wrapper function for position-try-fallbacks no longer exists (#10320). You can write the values directly without the wrapper.
anchor(center)
Centering a target used to require a convoluted syntax. The working group resolved (#8979) to add anchor(center):
.target {
left: anchor(center);
}
Browser Bugs
A few implementation bugs have also crept in. The spec states that if an element has no default anchor, position-area should do nothing. That's a known issue (#10500), but you can still trigger the buggy behavior, which centers the element inside its container even without an anchor.
The position-visibility property has a similar discrepancy. The spec says the initial value is anchors-visible, meaning the target hides when the anchor scrolls off-screen. Chrome currently treats always as the default instead.
Chrome currently isn't reflecting the spec. It indeed is using always as the initial value. But the spec's text is intentional — if your anchor is off-screen or otherwise scrolled off, you usually want it to hide (#10425).
Accessibility Considerations
Anchor positioning is often used for tooltips, popovers, and infoboxes, but it can also connect arbitrary elements — for example, drawing lines between elements for visual effect. Tethering elements visually doesn't create a semantic relationship. Screen readers see two unrelated elements side by side. For decorative connections, that's fine. For tooltips, you need a real connection.
The Popover API establishes an anchor relationship for you. More generally, the spec points to ARIA attributes such as aria-details or aria-describedby along with a role attribute on the target element. The CSS connects the visuals:
.anchor {
anchor-name: --my-anchor;
}
.toolip {
position: absolute;
position-anchor: --my-anchor;
position-area: top;
}
<div class="anchor" aria-describedby="tooltipInfo">anchor</div>
<div class="toolip" role="tooltip" id="tooltipInfo">toolip</div>
That gives you both a visual and semantic link, though it would be nicer not to need ARIA at all. Anchor positioning is still early, so expect more changes and more quirks as the spec matures.



