DEV Community

Nick Benksim
Nick Benksim

Posted on • Originally published at csscodelab.com

Anchor Positioning in CSS

Stop Wrangling Tooltips: The Magic of CSS Anchor Positioning

Picture this: you’re building a sleek dashboard, and you need a tooltip to hover perfectly above a specific button. But wait, that button is inside a scrollable container. Or maybe it’s buried deep within a nested div with overflow: hidden. Suddenly, your “simple” tooltip is clipped, or worse, it’s floating ten miles away from where it should be. We’ve all been there, staring at the screen and wondering why such a basic UI pattern feels like fighting a final boss in a video game.

Anchor Positioning is the industry’s answer to this madness. It’s a declarative way to tell the browser: “See that element? Stick this other element to it, no matter what happens to the layout.” It’s native, it’s performant, and it’s finally making our lives easier.

How we suffered before (The Dark Ages of JS Libraries)

Before Anchor Positioning became a reality, we had two main ways to handle “tethered” UI elements, and both kind of sucked. First, there was the “CSS Hack” approach: using position: absolute inside a position: relative parent. This worked until you encountered a layout where the parent couldn’t contain the child, forcing you into a battle with z-index and stacking contexts.

When CSS failed, we reached for the heavy artillery: JavaScript. We used getBoundingClientRect() to manually calculate coordinates every time the window resized or the user scrolled. Libraries like Popper.js or Floating UI became mandatory dependencies just to show a menu. While those tools are brilliant, they add extra KB to your bundle and require manual lifecycle management. We even tried to mitigate some of these issues by styling native HTML elements like dialog and popover, but even then, precise positioning often still required a touch of JS magic.

The modern way in 2026: Purely Declarative

The modern approach moves all that logic back into CSS. Instead of calculating pixels, you define an anchor-name on the target element and then use the anchor() function on the positioned element. The browser takes over the heavy lifting, ensuring the elements stay glued together during scrolls, resizes, and even layout shifts.

What makes this truly “senior-level” is how it handles edge cases. You can define “position fallback” logic, telling the browser: “Try to put the tooltip on top, but if it hits the edge of the viewport, flip it to the bottom.” This used to be 50 lines of logic; now it’s just a few lines of CSS. To keep your styles organized while implementing these new features, I highly recommend using Cascading CSS Layers (@layer) to separate your positioning logic from your component themes.

Ready-to-use code snippet

Here is a minimal, robust example of how to link a tooltip to a button using the Anchor Positioning API. Note how we use anchor-name on the anchor and position-anchor on the target.


/* The 'Anchor' element (the button) */
.anchor-button {
  anchor-name: --my-button;
  padding: 10px 20px;
  background: #007bff;
  color: white;
  border: none;
  border-radius: 4px;
}

/* The 'Anchored' element (the tooltip) */
.tooltip {
  position: fixed; /* Must be absolute or fixed */
  position-anchor: --my-button;
  
  /* Stick the bottom of the tooltip to the top of the button */
  bottom: anchor(top);
  /* Center it horizontally relative to the button */
  left: anchor(center);
  transform: translateX(-50%);
  
  /* Some styling sugar */
  margin-bottom: 8px;
  padding: 8px;
  background: #333;
  color: #fff;
  border-radius: 4px;
  font-size: 12px;
  white-space: nowrap;
}

Common beginner mistake: The “Invisible Anchor”

The biggest trap developers fall into when first using this API is forgetting that the anchored element must have its position property set to absolute or fixed. If you leave it as static (the default), the anchor() functions will simply return 0, and your tooltip will sit at the top-left of the page like a lost puppy.

Another “gotcha” is scope. The anchor-name is a dashed-ident (like a CSS variable). If you have multiple tooltips on a page, each anchor needs a unique name, or you need to use the implicit anchoring syntax. Don’t try to reuse the same name for twenty different buttons, or the browser will just pick the last one in the DOM and ignore the rest!

🔥 We publish more advanced CSS tricks, ready-to-use snippets, and tutorials in our Telegram channel. Subscribe so you don’t miss out!

Top comments (0)