Apple has released Safari 19, introducing native support for CSS Anchor Positioning. This API allows developers to position elements relative to other target elements on the page using pure CSS.
It eliminates the need for heavy JavaScript layout calculations for tooltips and dropdowns.
The Tooltip Placement Problem
Historically, positioning a tooltip or dropdown required measuring coordinate boxes in JavaScript. If the page scrolled or the window resized, the coordinates had to be recalculated.
This often caused layout shifts or stuttering during scrolling.
| Performance / Feature | JS-based (Floating UI / Popper) | Native CSS Anchor Positioning |
|---|---|---|
| Main Thread Block | Yes (Scroll listeners) | No (Compositor level) |
| Bundle Overhead | ~5KB to 15KB | 0KB (Native CSS) |
| Layout Shift Jitter | Common on fast scroll | Zero (Browser-optimized) |
| Setup Complexity | High (Ref required) | Low (Pure CSS selectors) |
Libraries like Popper.js and Floating UI solved this, but they added extra weight to your bundle.
Pure CSS Anchor Coordinates
With CSS Anchor Positioning, you define the relationship directly in style sheets. You mark one element as the anchor and position the target relative to it.
<!-- HTML Popover trigger -->
<button id="my-anchor" popovertarget="my-tooltip">Options</button>
<div id="my-tooltip" popover>Tooltip info!</div>
/* CSS setup linking the two elements */
#my-anchor {
anchor-name: --anchor-options;
}
#my-tooltip {
position: absolute;
position-anchor: --anchor-options;
bottom: anchor(top);
left: anchor(center);
margin-bottom: 8px;
}
The browser handles all positioning and recalculations internally. This results in smoother rendering.
Automatic Fallback Handling
The API also supports automatic positioning fallbacks. If there isn't enough space to display a tooltip above the anchor, the browser will automatically position it below.
You can configure fallback strategies using @position-try declarations:
#my-tooltip {
position: absolute;
position-anchor: --anchor-options;
/* Top is primary, fallback to bottom if no space */
position-try-options: --bottom-fallback;
}
@position-try --bottom-fallback {
top: anchor(bottom);
bottom: auto;
margin-top: 8px;
}
This reduces the complexity of managing viewport boundaries in your code.
Tagged with
Written by
DebuggerMe TeamThe DebuggerMe team builds developer tools, writes technical content, and helps teams ship better software.
Related Articles
All articles →CSS Grid vs Flexbox: When to Use Each (With Real Examples)
The grid vs flexbox debate persists because developers treat them as alternatives. They're not, they solve different problems. This guide shows you exactly when to reach for each one.
React 19 Stable Is Finally Here
React 19 has entered stable release, introducing the React Compiler, server actions, and cleaner async form handling hooks.
Stop Writing API Wrappers. Use TanStack Query Instead
Most frontend codebases have a homegrown API layer full of useEffect hacks, loading booleans, and stale data bugs. TanStack Query solves all of these in 20 lines. Here's how to migrate.