CSS3 min read
CSS Anchor Positioning
Position elements relative to other elements — tooltips, popovers, dropdowns
S
Shahar Amir
CSS Anchor Positioning
Finally! Position elements relative to other elements without JavaScript.
The Problem
Tooltips, dropdowns, and popovers need to:
- Position relative to a trigger element
- Stay in viewport
- Update on scroll/resize
Before: JavaScript libraries like Floating UI. Now: Pure CSS.
Basic Syntax
css
1234567891011121314
/* Define an anchor */.button { anchor-name: --my-anchor;}
/* Position relative to anchor */.tooltip { position: absolute; position-anchor: --my-anchor; /* Place below the anchor */ top: anchor(bottom); left: anchor(center);}Anchor Functions
Position relative to anchor edges:
css
1234567891011
.tooltip { /* Anchor edges */ top: anchor(bottom); /* Below anchor */ bottom: anchor(top); /* Above anchor */ left: anchor(left); /* Align left edges */ right: anchor(right); /* Align right edges */ /* Center */ left: anchor(center); /* Horizontally centered */ top: anchor(center); /* Vertically centered */}With Offset
Add spacing:
css
12345
.tooltip { top: calc(anchor(bottom) + 8px); left: anchor(center); translate: -50% 0;}Automatic Positioning
Let browser choose best position:
css
1234567891011
.tooltip { position: absolute; position-anchor: --trigger; /* Try bottom first, fall back to top */ position-try: bottom, top, right, left;}position-try-fallbacks
More control over fallbacks:
css
12345678910111213
.dropdown { position-anchor: --menu-button; /* Primary position */ top: anchor(bottom); left: anchor(left); /* Fallback positions */ position-try-fallbacks: flip-block, /* Flip to top if no space */ flip-inline, /* Flip horizontally */ flip-block flip-inline; /* Flip both */}Real Example: Tooltip
html
12
<button class="trigger">Hover me</button><div class="tooltip">I'm a tooltip!</div>css
12345678910111213141516171819202122232425262728293031
.trigger { anchor-name: --tooltip-anchor;}
.tooltip { /* Hidden by default */ opacity: 0; pointer-events: none; /* Positioning */ position: absolute; position-anchor: --tooltip-anchor; top: calc(anchor(bottom) + 8px); left: anchor(center); translate: -50% 0; /* Styling */ background: #333; color: white; padding: 8px 12px; border-radius: 6px; /* Auto-flip if no space below */ position-try-fallbacks: flip-block; transition: opacity 0.2s;}
.trigger:hover + .tooltip { opacity: 1;}With Popover API
Even better with the Popover API:
html
123456
<button popovertarget="menu" class="trigger">Open Menu</button>
<div id="menu" popover class="menu"> <a href="#">Option 1</a> <a href="#">Option 2</a></div>css
12345678910
.trigger { anchor-name: --menu-trigger;}
.menu { position-anchor: --menu-trigger; top: anchor(bottom); left: anchor(left); margin: 0;}Inset Shorthand
Position all sides at once:
css
1234567
.overlay { position: absolute; position-anchor: --card; /* Cover the anchor exactly */ inset: anchor(top) anchor(right) anchor(bottom) anchor(left);}Browser Support
Chrome and Edge have full support. Firefox and Safari are implementing.
Feature detect:
css
123
@supports (anchor-name: --test) { /* Use anchor positioning */}Why It Matters
- No JavaScript for positioning
- Automatic fallbacks for viewport edges
- Declarative — easier to maintain
- Performance — browser-optimized
This is how tooltips and dropdowns should work.
#positioning#popover#modern-css
Stay Updated 📬
Get the latest tips and tutorials delivered to your inbox. No spam, unsubscribe anytime.