The End of Popper.js: CSS Anchor Positioning Arrives

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:

  1. anchor-name: Identifies an element as an anchor
  2. position-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:

  1. Zero layout thrashing: No JavaScript reads of getBoundingClientRect()
  2. No reflow on scroll: CSS handles position updates natively
  3. Reduced JavaScript bundle: Drop 10-30KB of library code
  4. 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.

Share this post