The End of Popper.js: CSS Anchor Positioning Arrives
For a decade, frontend developers have relied on JavaScript libraries like Popper.js and Floating UI to solve one of web development's most annoying problems: positioning floating elements relative to their triggers. Tooltips, dropdowns, popovers, context menus—they all need to sit next to the button that spawned them, handle viewport collisions, and reposition intelligently.
In 2026, CSS finally has a native solution. Anchor Positioning is here, and it's about to make a whole category of JavaScript libraries obsolete.
The Problem We've All Lived With
Before diving into the solution, let's remember the pain:
// The old way (simplified)
const button = document.querySelector('#button');
const tooltip = document.querySelector('#tooltip');
const buttonRect = button.getBoundingClientRect();
const tooltipRect = tooltip.getBoundingClientRect();
let top = buttonRect.top - tooltipRect.height - 8;
let left = buttonRect.left + (buttonRect.width / 2) - (tooltipRect.width / 2);
// Check if it goes off-screen...
if (top < 0) {
top = buttonRect.bottom + 8;
}
// Check viewport edges...
if (left < 0) {
left = 8;
}
tooltip.style.top = `px`;
tooltip.style.left = `px`;
// And re-calculate on scroll, resize, window changes...
This was the state of the art. We needed JavaScript for something as fundamental as "put this thing next to that thing."
Enter CSS Anchor Positioning
Anchor positioning introduces two new CSS concepts:
anchor-name: Identifies an element as an anchorposition-anchor: Tells another element to position itself relative to that anchor
Here's the modern equivalent:
/* Step 1: Define the anchor */
.trigger-button {
anchor-name: --my-anchor;
}
/* Step 2: Position relative to anchor */
.tooltip {
position: absolute;
position-anchor: --my-anchor;
bottom: anchor(top);
left: anchor(center);
transform: translateX(-50%);
}
That's it. No JavaScript. No recalculations. No library dependencies.
The inset-area Property: Magic for Collision Handling
The real power move is inset-area—a property that tells the browser where you'd prefer the element to go, while letting it figure out the best placement based on available space.
.tooltip {
position-anchor: --my-anchor;
inset-area: top; /* Prefer top, but auto-adjust if needed */
}
The inset-area property accepts values like:
| Value | Description |
|---|---|
top |
Position above the anchor |
bottom |
Position below the anchor |
left |
Position to the left |
right |
Position to the right |
top-start, top-end |
Corners of the anchor |
span-all |
Let browser decide best position |
The browser automatically detects collisions and repositions. If your tooltip would flow off the top of the viewport, it flips to the bottom. No JavaScript required.
Real-World Examples
Dropdown Menu
.menu-button {
anchor-name: --menu-trigger;
}
.dropdown {
position: fixed;
position-anchor: --menu-trigger;
inset-area: bottom;
margin-top: 4px;
}
Context Menu (Right-Click)
.context-target {
anchor-name: --ctx-anchor;
}
.context-menu {
position: fixed;
position-anchor: --ctx-anchor;
bottom: anchor(end);
left: anchor(start);
}
Complex Tooltip with Multiple Positions
.tooltip {
position-anchor: --trigger;
inset-area: top span-inline; /* Try top first, fallback to inline */
}
/* Fallback styling for when position changes */
.tooltip:position-try-bottom {
/* Different arrow direction */
}
Browser Support in 2026
The rollout is happening now:
| Browser | Status | Version |
|---|---|---|
| Chrome/Edge | ✅ Full support | 129+ |
| Firefox | 🔄 In development | Behind flag in 2026 |
| Safari | 🔄 Technical preview | Expected stable 2026 |
Chrome and Edge users get the full experience today. Firefox and Safari are shipping imminently—this is the time to start experimenting.
Progressive Enhancement Strategy
Here's how to implement it with a JavaScript fallback:
/* Modern browsers */
@supports (anchor-name: none) {
.tooltip {
position: absolute;
position-anchor: --my-anchor;
inset-area: top;
}
}
/* Fallback for older browsers */
@supports not (anchor-name: none) {
.tooltip {
position: absolute;
top: -40px;
left: 50%;
transform: translateX(-50%);
}
}
Or use JavaScript detection:
if (CSS.supports('anchor-name', 'none')) {
// Use native anchor positioning
document.documentElement.classList.add('anchor-positioning');
} else {
// Fall back to Popper.js or Floating UI
initFallbackPositioning();
}
What This Means for the Ecosystem
Libraries Becoming Obsolete
- Popper.js: No longer needed for basic positioning
- Floating UI: Still useful for complex virtualization, but core positioning is now native
- React Popper / Material UI Popover: Can simplify significantly
What's Still Useful
JavaScript positioning libraries aren't dead entirely. They still provide:
- Virtual scrolling for very long lists
- Portal management for z-index wars
- Advanced animations and transitions
- IE11 support (if you still need it)
But the core positioning logic? That's CSS's job now, as it always should have been.
Performance Benefits
Moving positioning logic to CSS has measurable advantages:
- Zero layout thrashing: No JavaScript reads of
getBoundingClientRect() - No reflow on scroll: CSS handles position updates natively
- Reduced JavaScript bundle: Drop 10-30KB of library code
- Smoother animations: CSS transitions on positioned elements work naturally
Accessibility Improvements
Native CSS positioning plays nicer with assistive technology:
.tooltip[role="tooltip"] {
position-anchor: --trigger;
inset-area: top;
}
Screen readers see the semantic relationship more clearly, and focus management becomes more predictable.
Getting Started Today
Step 1: Add Anchor Names
button[data-tooltip] {
anchor-name: var(--tooltip-anchor);
}
Step 2: Position Your Floating Elements
[data-tooltip]::after {
content: attr(data-tooltip);
position: fixed;
position-anchor: var(--tooltip-anchor);
inset-area: bottom;
margin-top: 8px;
padding: 4px 8px;
background: #1a1a1a;
color: white;
border-radius: 4px;
font-size: 14px;
}
Step 3: Test in Chrome/Edge
Open DevTools and verify your elements position correctly. Watch how they handle viewport edges.
Step 4: Add Fallbacks
Use @supports or JavaScript detection for browsers that don't support anchor positioning yet.
The Future Is Native
CSS Anchor Positioning represents a philosophical shift in web development: things that belong in CSS should stay in CSS. Positioning floating elements relative to triggers is fundamentally a layout concern, not a logic one.
For years, we reached for JavaScript because CSS couldn't handle it. In 2026, that excuse is gone.
Your tooltips won't miss Popper.js. Your dropdowns won't miss Floating UI. And your bundle sizes will thank you.
Ready to dive deeper? Check out the MDN documentation or W3C specification.