Skip to main content
The 2026 AI Readiness ReportRead it
The journal
Engineering·September 2026·8 min

The CSS Anchor Positioning specification solved the floating element problem properly.

CSS Anchor Positioning became Baseline Newly Available on 13 January 2026, when Firefox 147 shipped support, completing the cross-browser picture that Chrome and Edge started in May 2024 and Safari finished in September 2025. Combined with the Popover API, which reached Baseline in 2024, the platform now handles both the position calculation with overflow detection and the layer management that JavaScript tooltip libraries have spent a decade providing. The specification is more considered than most tutorial coverage suggests.

SG
Sher Ghan
Principal AI Engineer
The CSS Anchor Positioning specification solved the floating element problem properly.

The pitch for CSS Anchor Positioning gets compressed in most coverage into 'tooltips without JavaScript,' which is accurate and undersells the specification. The floating element problem, keeping a positioned element tethered to another element as the page scrolls, the viewport resizes, and the anchor moves, has been solved by libraries through JavaScript: event listeners, position calculations on every relevant frame, and a separate mechanism to manage the z-index layer. The specification solves it through the layout algorithm, which is the correct place for it to be.

Firefox 147 added support without a flag on 13 January 2026, completing the Baseline Newly Available picture. Chrome and Edge had shipped in version 125 in May 2024. Safari followed in version 26 in September 2025. Baseline Newly Available means all three major browser engines have implemented the feature and consider it stable. As of September 2026, coverage across tracked global browser traffic sits above 88 per cent. The related Popover API, which handles the layer management side of the same problem, reached Baseline in 2024; the two specifications are designed to compose.

What the specification defines

The CSS Anchor Positioning Module Level 1, published at w3.org/TR/css-anchor-position-1/, establishes a tethering relationship between two elements using two new CSS properties. The anchor-name property declares that an element can act as an anchor and assigns it a dashed identifier. The position-anchor property on the positioned element names which anchor it is tethered to. With that relationship declared, the positioned element can reference the anchor's edges in its positioning properties using the anchor() function: anchor(top) evaluates to the top edge of the anchor in the positioned element's coordinate system, anchor(center) to the horizontal centre. These evaluate during the layout pass, before any painting happens, with no event listeners required.

The position-area property is a higher-level interface for the most common placements. It models the anchor as the centre of a three-by-three grid of regions and lets you declare which region the positioned element should occupy. The value 'top center' positions the element above the anchor, horizontally centred on it. Logical values such as 'block-start inline-end' work correctly for right-to-left layouts. For standard placements, this removes most of the offset arithmetic that the anchor() function would otherwise require.

One naming note the specification's history makes relevant: the position-area property was called inset-area in early Chromium implementations and in documentation written during the experimental phase. The W3C CSS Working Group published an update in May 2025 confirming the shipped property name. Code and tutorials from before mid-2025 may use the earlier name.

@position-try and overflow detection

The @position-try at-rule is where the specification addresses the problem that occupies most of the code in a JavaScript floating element library. The core behaviour that Floating UI, Popper.js's successor, provides is overflow detection: the library calculates whether the positioned element would overflow its scroll container in the desired placement and repositions it if so. A tooltip that should appear above its trigger needs to flip below it when the trigger is near the top of the viewport. Floating UI does this calculation in JavaScript on scroll and resize events. @position-try declares the fallback strategy as CSS, and the browser resolves it during layout.

The at-rule defines a named fallback: a block of CSS properties describing an alternative placement. The position-try-fallbacks property on the positioned element lists which strategies to try in order. When the browser calculates that the primary placement would overflow the containing block, it works through the fallback list, using the first placement that does not overflow. You can name as many strategies as the design requires, stacking them in priority order: flip above, then flip below, then a compact variant that shifts sideways. The browser resolves the correct one during the layout pass, before any painting happens.

What Floating UI is doing is the same logical work, but in a different part of the rendering pipeline: one that runs after the browser has already shown the user something. Under ordinary conditions this is not perceptible. On low-end devices, on elements that track position during scroll, and in complex layouts where position recalculation triggers a chain of dependent layout updates, the difference in when the calculation runs becomes measurable. Anchor positioning does not eliminate the recalculation; it moves it to where the browser's own layout algorithm can absorb it.

“What Floating UI is doing is the same logical work, but in a different part of the rendering pipeline: one that runs after the browser has already shown the user something.”

Composing with the Popover API

The Popover API, which reached Baseline in 2024 across Chrome 114, Safari 17, and Firefox 125, handles the layer management that anchor positioning does not. A popover element is automatically placed in the browser's top layer; it paints above all non-top-layer content without any z-index declaration. The popover attribute with a value of 'auto' provides light dismiss: clicking outside the popover closes it, and pressing Escape does the same. A button element wired to a popover via the popovertarget attribute opens and closes it with no JavaScript.

The two specifications compose because the popover's top-layer placement removes the z-index problem, and anchor positioning tethers the popover to its trigger. The anchor relationship is declared in CSS: the trigger element is named with anchor-name, the popover references it with position-anchor, the position-area property places it, and @position-try handles overflow. The result is a positioned, overflow-aware, dismissible floating element whose position is resolved at layout time and whose stacking requires no manual management.

The anchor relationship in CSS is not constrained by DOM structure. The trigger and the popover can be anywhere in the document tree; the tethering works regardless of nesting or source order. This removes a constraint that pushed some component libraries toward DOM manipulation: moving the floating element to a portal at the document root in order to escape a parent's overflow hidden or z-index context. The top-layer placement of popovers solves that problem independently of where the element appears in the DOM.

What anchor positioning does not replace

Anchor positioning handles position and overflow. It does not handle animation on open and close. The @starting-style rule, available in all major engines since 2024, lets you define the element's initial rendered state before it transitions into visibility, which handles entry animation without JavaScript. Exit animation is harder: CSS has no native mechanism to delay removal from the top layer until an outgoing animation completes. Animated close transitions still require JavaScript, in practice meaning a class toggle coordinated with a transitionend event.

Component libraries such as Radix, Headless UI, and Ariakit handle interactive state, keyboard navigation, focus management, and accessibility tree semantics that neither the Popover API nor anchor positioning address. Their position calculations and z-index management can now be delegated to the platform, which is what Floating UI's maintainers have said they intend to do. The libraries themselves are not made unnecessary; one layer of their responsibility is.

The documentation ecosystem is still normalising. MDN's coverage is thorough and uses the correct property names. Tutorial content written before mid-2025 often uses inset-area rather than position-area. Browser DevTools support for inspecting anchor relationships is present in Chrome's layout panel and in development in other engines. The feature reached Baseline eight months ago and has not yet made it into most front-end hiring criteria.

The floating element problem is older than the libraries that solved it. CSS has been able to position elements since the late 1990s; tethering one element to another in response to scroll and layout changes required JavaScript because the platform provided no native mechanism. CSS Anchor Positioning closes that gap without requiring DOM adjacency between the anchor and the positioned element, with overflow detection handled declaratively, and at the layer where the browser's layout algorithm runs. Reading the specification before the tutorials reach you costs an afternoon. The property model is narrow and the key sections are short.

About the author

Sher Ghan

Principal AI Engineer

Every piece in the Journal is written personally by a senior practitioner, drawing on the engagement that motivated it. No ghostwriters, no content team, no models. If a paragraph here resonates with a problem you are looking at, the author is the person to reply to.

Get in touch with the practice