How CSS position-anchor Binds Tooltips to Elements

The CSS position-anchor property is a core feature of the CSS Anchor Positioning API that connects an absolutely positioned element, such as a tooltip, to a specific reference element on the page. By establishing this relationship directly in CSS, developers can bind floating UI components to their triggers without relying on nested DOM structures or JavaScript positioning libraries. This article explains how position-anchor works, how it pairs with the anchor-name property, and how to use it to position a tooltip relative to its trigger.

The Mechanism Behind Anchor Positioning

Traditionally, positioning a tooltip relative to an arbitrary element required calculating coordinates using JavaScript or placing the tooltip inside the trigger element with position: relative. The CSS Anchor Positioning specification solves this natively through a two-step association: naming the trigger and referencing that name on the anchored element.

Step 1: Naming the Trigger Element

To make an element available as an anchor point, you assign it an identifier using the anchor-name property. The identifier must be a dashed-ident (prefixed with --), similar to a CSS custom property.

.tooltip-trigger {
  anchor-name: --trigger-button;
}

This declaration registers --trigger-button in the browser's positioning context as an available anchor point.

Step 2: Referencing the Trigger with position-anchor

The position-anchor property is applied to the anchored element—the tooltip. Setting this property tells the tooltip which anchor element to use as its default reference point for coordinates.

.tooltip {
  position: absolute;
  position-anchor: --trigger-button;
}

Once position-anchor is declared, the tooltip is logically bound to --trigger-button.

Step 3: Aligning with the anchor() Function

Declaring position-anchor sets the default target, but it does not place the tooltip in space on its own. To physically align the tooltip to the trigger's edges, you use the anchor() function in directional inset properties (top, bottom, left, right).

When position-anchor is active, the anchor() function defaults to that specified anchor without requiring you to pass the anchor's name inside every function call:

.tooltip {
  position: absolute;
  position-anchor: --trigger-button;
  
  /* Positions the bottom of the tooltip to the top edge of the trigger */
  bottom: anchor(top);
  
  /* Centers the tooltip horizontally relative to the trigger */
  left: anchor(center);
  transform: translateX(-50%);
}

Without position-anchor, you would have to write bottom: anchor(--trigger-button top) for every property. The position-anchor property streamlines the code by defining the scope globally for that element.

Benefits of the Native Binding

  • DOM Independence: The trigger and the tooltip can live in completely different parts of the HTML document, which is ideal for avoiding overflow: hidden clipping and z-index stacking context traps.
  • Automatic Updates: Because the browser engine handles the binding natively, the tooltip maintains its position when the page scrolls, resizes, or dynamically shifts, eliminating the jitter often seen with script-based positioning.
  • Fallback Handling: Combined with position-try-fallbacks, bound elements can automatically shift their placement if they risk rendering outside the viewport.