demo · v131

Ancestor-scoped component anchors

The planning use case wasn't just "lists with duplicate anchor names". It was components: a reusable date-picker, menu, or popover that hard-codes an internal anchor-name needs to make sure a second copy on the page doesn't leak anchors outside its own subtree. Here the anchor-scope declaration lives on an ancestor wrapper around each trigger and popover.

scope host:
component a

menu inside component A

ancestor scope host
component b

menu inside component B

ancestor scope host

Toggle the ancestor scope host. The computed values below show that anchor-scope is applied to the wrapper, not inherited by the trigger. The outside-observer check creates a temporary popover outside both wrappers and reports whether this browser lets it resolve the internal anchor name.

host A computed checking…
trigger computed checking…

The child trigger keeps anchor-scope: none; the ancestor wrapper does the scoping.

outside observer checking…

the css

/* ancestor wrapper scopes the names inside this subtree */
.component-shell {
  anchor-scope: --menu-anchor;
}

/* internal trigger declares the reusable name */
.component-shell .menu-trigger { anchor-name: --menu-anchor; }

/* internal popover resolves only within the same scoped subtree */
.component-shell .menu-popover {
  position: absolute;
  position-anchor: --menu-anchor;
  top: anchor(bottom);
  left: anchor(left);
}

contrast with the list demo

The companion list demo illustrates the bug at row scope. This one shows the same idea as a reusable component shell: the scope host is an ancestor of the internal anchor and the internal positioned box, so a design system can ship a popover, tooltip, or autocomplete with stable internal names.

see also