Every tooltip and dropdown library exists to solve one problem: keep element B positioned relative to element A, correctly, even as the page scrolls, resizes, or the anchor moves. That's a surprisingly involved calculation once you account for viewport edges, and it's exactly the calculation CSS anchor positioning now does natively.
TL;DR:
anchor-nameon a trigger element andposition-anchorplusanchor()on a positioned element tie the two together natively in CSS, no JavaScript position calculation required. Combined with the HTMLpopoverattribute for top-layer rendering and light-dismiss, this covers the common tooltip and dropdown pattern that Popper.js and Floating UI existed to solve, for browsers that support it.
The Basic Anchor-to-Tooltip Link
.trigger-button {
anchor-name: --my-tooltip-anchor;
}
.tooltip {
position: fixed;
position-anchor: --my-tooltip-anchor;
top: anchor(bottom);
left: anchor(center);
translate: -50% 8px;
}
<button class="trigger-button">Hover me</button>
<div class="tooltip" popover>Helpful tooltip text</div>
anchor-name gives the button a named anchor reference. position-anchor on the tooltip points at that name, and anchor(bottom)/anchor(center) compute the tooltip's top/left relative to the anchor's actual rendered position, bottom edge and horizontal center respectively. This recalculates automatically on scroll and resize, the same behavior Floating UI's autoUpdate() exists to provide manually.
Fallback Positions With @position-try
.tooltip {
position: fixed;
position-anchor: --my-tooltip-anchor;
top: anchor(bottom);
left: anchor(center);
translate: -50% 8px;
position-try-fallbacks: flip-block;
}
@position-try flip-block {
top: anchor(top);
bottom: unset;
translate: -50% -8px;
}
position-try-fallbacks: flip-block tells the browser: if the tooltip would overflow the viewport in its preferred position (below the anchor), try the flip-block fallback instead (above the anchor). Several built-in try-tactic keywords exist (flip-block, flip-inline, flip-start) covering the common flip cases without a custom @position-try block at all, worth checking before writing a manual fallback.
Combining With popover for a Full Dropdown
<button popovertarget="user-menu" class="menu-trigger">Account</button>
<div id="user-menu" popover class="dropdown-menu">
<a href="/profile/">Profile</a>
<a href="/settings/">Settings</a>
<a href="/logout/">Log out</a>
</div>
.menu-trigger {
anchor-name: --user-menu-anchor;
}
.dropdown-menu {
position-anchor: --user-menu-anchor;
top: anchor(bottom);
right: anchor(right);
margin-top: 4px;
}
popovertarget on the button wires up open/close behavior, focus handling, and light-dismiss (clicking outside closes it) entirely through HTML attributes, no JavaScript addEventListener needed for that part either. anchor-name/position-anchor handle where it appears. Together, this is a complete dropdown menu, positioning, top-layer rendering, dismiss behavior, and keyboard accessibility, without a single line of JavaScript or a dependency.
Sizing the Positioned Element to Match Available Space
.dropdown-menu {
position-anchor: --user-menu-anchor;
top: anchor(bottom);
right: anchor(right);
max-height: anchor-size(height); /* size relative to the anchor's own height, if useful */
max-width: 320px;
overflow-y: auto;
}
anchor-size() reads a dimension from the anchor element itself, useful for a dropdown that should match its trigger's width exactly (width: anchor-size(width);), rather than having a fixed or content-based width unrelated to the button that opened it.
Browser Support and the JavaScript Fallback Story
Anchor positioning shipped in Chrome and Edge in 2024, with Firefox and Safari following through 2025 and into 2026. For the remaining gap, this is a feature where a JavaScript fallback still matters more than most CSS features covered elsewhere in this series, an unsupported browser doesn't gracefully degrade to "no positioning," it renders the tooltip at its default static position, likely overlapping other content. Feature-detect with @supports (anchor-name: --a) and load Floating UI conditionally only for browsers that fail that check, rather than assuming universal support the way you reasonably could with :has() or scroll-driven animations by 2026.
Old Way vs Modern Way
| Task | Before | With anchor positioning |
|---|---|---|
| Tooltip stays attached to its trigger | Floating UI / Popper.js, JS position calc | anchor-name + anchor() |
| Recalculate on scroll/resize | Manual autoUpdate() listener | Automatic, native |
| Flip to avoid viewport overflow | Manual collision detection logic | position-try-fallbacks |
| Dropdown open/close, focus, dismiss | Custom JS or a UI library | HTML popover attribute |
Conclusion
Anchor positioning doesn't add a capability CSS never had a workaround for, it removes the JavaScript dependency that workaround required. For a straightforward tooltip or dropdown, anchor-name/anchor() combined with the popover attribute covers what Floating UI existed to solve, with the caveat that support isn't universal enough yet to drop the JavaScript fallback for every project without checking your actual browser support requirements first.