ShaharAmir
← Back to Blog
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.