CSS 与布局 / CSS Anchor Positioning · 把元素钉在另一个元素旁 / 两个角色与跨包含块的定位 待审核 1 / 7
why · 心智模型

两个角色与跨包含块的定位

需求始终是同一个:让浮层贴着某个元素出现。在 anchor positioning 之前只有两条路径,各自都有代价。把浮层放进锚的 position: relative 容器,它会被 overflow 裁掉、被 z-index 压住;用 JS 读 getBoundingClientRect() 手算坐标,则要监听滚动与 resize 反复重算。

当前浏览器对 anchor positioning 的实测支持情况,由 CSS.supports() 探测。本系列每页顶部都有这条横幅。

1 · 传统方案的局限

图 1-1 · relative 容器方案与 JS 手算方案的并排对照。可切换滚动与容器裁剪,观察两种方案各自失效的位置。

2 · 锚元素与浮层的两个属性

整套机制只有两个角色。被参照的元素是锚元素,用 anchor-name 起名;要摆位的元素是浮层,用 position-anchor 指明它参照谁。

图 2-1 · anchor-nameposition-anchor 的对应关系。可改锚名观察绑定的建立与断开。

注 · 锚名 --x 是 dashed-ident,写法像 CSS 自定义属性,却不是变量,不能套 var()。浮层须是 position: absolutefixed 才能用 anchor()position-anchor 指定的是默认锚,指定之后 anchor() 里可以省略锚名。

3 · 无 JS 重算的跟随

图 3-1 · 拖动锚元素时浮层的跟随。拖动只改锚自身的 left / top,浮层的落点由 CSS 计算得出,页面上没有监听坐标或手动 reposition 的 JS。

4 · 脱离裁剪与包含块的约束

同一个藏在裁剪盒里的按钮,传统方案中 tooltip 是盒子的子元素,被 overflow: clip 切掉一半;anchor positioning 让 tooltip 成为盒子外部的兄弟元素,却锚定盒子内部的按钮,完整显示且不受裁剪。

图 4-1 · 裁剪盒内的锚与盒外的浮层。左侧 tooltip 作为子元素被 overflow: clip 截断,右侧 tooltip 作为兄弟元素锚定盒内的按钮,完整显示。

浮层不必再是锚的子孙,因而不受 overflow、transform 与 stacking context 牵连,甚至可以待在 top layer。它视觉上贴着谁,与它在 DOM 中处于何处,在很大程度上解耦。本系列其余各页都建立在这一点上:popover 在 top layer、菜单挂在 body,都照样精确对齐。

警示 · 解耦不等于放哪都行。规范要求锚在布局上严格先于浮层,落到写法上即让两者做兄弟、锚写在前面,且浮层的包含块要能包住锚。实测 Chrome 151 在浮层写于锚之前时 anchor() 直接失效,浮层退回未锚定的位置(核对于 2026-08)。约束的完整口径见细节与边界页 §1。