← /lab

// live demo

Anchored UI

Tooltips, menus, and popovers that tether themselves to their triggers with native anchor-name + anchor() — no getBoundingClientRect, no scroll listeners, no JS math. Show/hide runs through the Popover API on the top layer, and position-try-fallbacks flips each popover automatically when it would spill past the viewport edge.

// 01 — tethered popover

The card below owns anchor-name: --hero. Its popover sets position-anchor: --hero, then position-area: bottom (sugar over anchor()) with justify-self: anchor-center. The browser does the geometry.

PriceTag

Tethered below its anchor with position-area: bottom + centered via anchor-center. The arrow is a pseudo-element centered under the popover.

position-anchor: --hero

// 02 — anchored tooltips

Each chip is its own anchor. The tooltip is a popover="hint" shown on hover/focus, placed above the chip with position-area: top and centered via anchor-center. Keyboard users get them too — tab through.

  • #ff006e · hot pink
  • #00d9ff · electric cyan
  • #fff95b · acid yellow
  • #0d0a1e · the dark

// 03 — anchored menu

A real menu on the top layer. The trigger anchors it; the panel uses position-try-fallbacks: flip-block so it opens upward when it would clip the bottom of the screen.

// 04 — automatic edge reflow

This is the magic. Drag the probe to a corner and open its popover. The default placement is below-right; when that would overflow, the browser walks position-try-fallbacks: flip-block, flip-inline, flip-block flip-inline and picks the first that fits. No resize listener. No JS.

Implementation: every popover is shown and hidden by the native Popover API — no JS toggles show/hide. Positioning is 100% CSS: anchors declare anchor-name, popovers reference them with position-anchor + the anchor() function, and overflow handling is position-try-fallbacks. The only script on this page makes the probe in row 04 draggable (so you can shove it into a corner) and reads back which fallback the browser chose — the layout itself never touches JS.