CSS Anchor Positioning: Tooltips and Dropdowns Without JavaScript
The End of Popper.js and Floating UI
For over a decade, positioning a tooltip relative to a button required JavaScript. Libraries like Popper.js, Floating UI, and Tippy.js existed solely because CSS had no way to say “put this element below that element.” You’d calculate bounding rects, handle scroll offsets, flip positions when near viewport edges, and manage resize observers.
CSS Anchor Positioning changes all of that. It’s now Baseline 2026 — supported in Chrome 125+, Firefox 147+, and Safari 26+. You can tether any positioned element to any anchor element using pure CSS, with built-in overflow handling and fallback positions. No JavaScript, no layout thrashing, no bundle bloat.
How Anchor Positioning Works
The system has two roles: the anchor (the element you’re pointing at) and the positioned element (the thing that floats near the anchor — your tooltip, dropdown, etc.).
Step 1: Name the Anchor
Give any element an anchor name using the anchor-name property. The name must start with a double dash, just like custom properties.
/* The button that tooltips will point to */
.trigger-button {
anchor-name: --tooltip-anchor;
}Step 2: Tether the Positioned Element
Link the floating element to the anchor using position-anchor, and use position-area for placement.
.tooltip {
/* Must be positioned */
position: fixed;
/* Link to the anchor */
position-anchor: --tooltip-anchor;
/* Place it above the anchor */
position-area: top;
/* Some breathing room */
margin-bottom: 8px;
}That’s it. The tooltip now sits above the button. No JavaScript. No getBoundingClientRect(). No resize observers. The browser handles everything, including repositioning on scroll.
The position-area Shorthand
The position-area property uses a 3×3 grid model centered on the anchor. You can place the positioned element in any of the 9 regions:
| Value | Position |
|---|---|
top | Centered above the anchor |
bottom | Centered below |
left | Centered to the left |
right | Centered to the right |
top left | Above and to the left |
top right | Above and to the right |
bottom left | Below and to the left |
bottom right | Below and to the right |
center | On top of the anchor |
For most tooltips and dropdowns, position-area is all you need. It’s concise, readable, and handles alignment automatically.
Pixel-Perfect Control With anchor()
When position-area isn’t precise enough, the anchor() function gives you exact positioning using the anchor’s edges.
/* Position the dropdown exactly at the bottom-left corner of the anchor */
.dropdown-menu {
position: absolute;
position-anchor: --nav-trigger;
/* Top of dropdown aligns with bottom of anchor */
top: anchor(bottom);
/* Left edge of dropdown aligns with left edge of anchor */
left: anchor(left);
/* Match the anchor's width */
width: anchor-size(width);
}The anchor() function accepts these edge keywords: top, bottom, left, right, center, start, end. And anchor-size() gives you the anchor’s width, height, block, or inline dimensions.
Automatic Overflow Handling
This is where CSS Anchor Positioning really outshines JavaScript libraries. When a tooltip is near the viewport edge and would overflow, you can define fallback positions that the browser will try automatically.
/* Define a fallback position */
@position-try --flip-to-bottom {
position-area: bottom;
margin-top: 8px;
margin-bottom: 0;
}
.tooltip {
position: fixed;
position-anchor: --tooltip-anchor;
position-area: top;
margin-bottom: 8px;
/* If there's no room on top, try bottom */
position-try-fallbacks: --flip-to-bottom;
}You can chain multiple fallbacks: position-try-fallbacks: --flip-to-bottom, --move-to-right, --move-to-left;. The browser tries each one in order until the element fits within the viewport.
For the common case of simple flips, there are built-in keywords you can use without defining @position-try blocks:
.tooltip {
position-area: top;
/* Built-in flip: try the opposite side if it overflows */
position-try-fallbacks: flip-block;
}The flip-block keyword flips vertically (top ↔ bottom), flip-inline flips horizontally (left ↔ right), and flip-block flip-inline flips both.
Pairing With the Popover API
The real power comes from combining anchor positioning with the native Popover API. This gives you fully accessible, zero-JavaScript tooltips and menus.
<!-- HTML: anchor + popover -->
<button popovertarget="menu" class="nav-item">
Settings ▾
</button>
<div id="menu" popover>
<ul>
<li>Profile</li>
<li>Preferences</li>
<li>Sign Out</li>
</ul>
</div>/* CSS: position the popover relative to its trigger */
.nav-item {
anchor-name: --settings-anchor;
}
#menu {
position-anchor: --settings-anchor;
position-area: bottom;
margin-top: 4px;
position-try-fallbacks: flip-block;
}What you get for free: keyboard support (Escape to close), light-dismiss (click outside to close), focus management, and top-layer rendering (no z-index wars). All without writing a single line of JavaScript.
Multiple Anchors
An element can reference multiple anchors. This is useful for connectors, lines between elements, or complex positioning that depends on multiple reference points.
.connector-line {
position: fixed;
/* Start from one element */
top: anchor(--start-node bottom);
left: anchor(--start-node center);
/* End at another element */
bottom: anchor(--end-node top);
right: anchor(--end-node center);
}The named anchor syntax — anchor(--name edge) — lets you reference any named anchor on the page, not just the one set with position-anchor.
Common Mistakes
1. Forgetting position: fixed or absolute
The positioned element must be absolutely or fixed positioned. Without this, position-anchor is silently ignored. You won’t get an error — the tooltip just won’t move.
2. Anchor Names Without the Double Dash
Writing anchor-name: tooltip instead of anchor-name: --tooltip is invalid CSS. The double dash prefix is required, just like custom properties.
3. Using Anchor Positioning for Modals
Anchor positioning is for elements that are tethered to a specific UI element. For full-screen modals that should be centered on the viewport, use <dialog> instead. Anchor positioning solves a different problem.
4. Not Testing Fallback Positions
If you define position-try-fallbacks, test them. Resize the viewport to trigger each fallback and make sure the tooltip still looks correct in every position.
Best Practices
- Use
position-areaoveranchor()when possible. It’s more readable and handles alignment automatically. Only reach foranchor()when you need pixel-level control. - Always define at least one fallback. A tooltip that disappears off-screen is worse than no tooltip. At minimum, add
position-try-fallbacks: flip-block;for vertical flipping. - Pair with the Popover API for interactive menus. You get accessibility, keyboard support, and light-dismiss for free. Don’t reinvent these behaviors in JavaScript.
- Use
anchor-size()to match widths. Dropdown menus that are the same width as their trigger button look polished.min-width: anchor-size(width);does this in one line. - Keep anchor names descriptive.
--main-nav-dropdownis better than--a1. You’ll be debugging these in DevTools eventually.
Wrapping Up
CSS Anchor Positioning eliminates the need for JavaScript positioning libraries in the vast majority of UI patterns. Tooltips, dropdowns, context menus, flyouts — they can all be built with a few CSS properties and zero runtime cost. Combined with the Popover API, you get accessible, performant overlay UI that works without a framework and degrades gracefully.
The API is stable across all major browsers as of 2026. If you’re still importing Floating UI or Popper.js, now’s the time to remove them.
FAQ
Can I animate the anchor-positioned element?
Yes. Standard CSS transitions and animations work on anchor-positioned elements. You can animate opacity, transform, and other properties. The position-area value itself isn’t animatable, but you can use @starting-style with the Popover API to create entry and exit animations.
Does anchor positioning work with CSS Grid or Flexbox layouts?
The anchor element can be inside any layout. However, the positioned element must be position: absolute or position: fixed, which takes it out of flow. The anchor positioning calculates position relative to the anchor regardless of the anchor’s layout container.
How does this compare to Floating UI?
For most use cases, CSS Anchor Positioning is a direct replacement. It handles placement, overflow detection, and fallback positions natively. Floating UI still has an edge for extremely complex cases — like virtual elements (anchoring to mouse position) or advanced middleware chains — but for standard tooltips and dropdowns, the CSS approach is simpler, faster, and has zero runtime cost.
What about accessibility?
Anchor positioning is purely visual — it doesn’t affect the DOM order or ARIA tree. You still need to handle focus management and ARIA attributes yourself (or use the Popover API, which handles them for you). Don’t rely on visual proximity alone for accessibility.
editor's pick
latest video
news via inbox
Nulla turp dis cursus. Integer liberos euismod pretium faucibua

