← ⚓ CSS Anchor Positioning · 把元素「钉」在另一个元素旁 / 为什么要它:两个角色 + 跨包含块的定位 待审核 1 / 7
why · 心智模型

为什么要它:两个角色 + 跨包含块的定位

需求始终是同一个:让浮层 B 贴着元素 A 出现。但在 anchor positioning 之前,你只有两条都不够理想的路径。

1 · 传统方案的局限

2 · 两个角色,两个属性

整套机制只有两个角色。给「被参照的」元素起个名字,给「要摆位的」浮层指明它参照谁:

锚名 --x 是个 dashed-ident(像 CSS 变量那样以 -- 开头,但不是变量,别用 var())。浮层必须是绝对/固定定位position: absolutefixed)才能用 anchor();position-anchor 指定它的默认锚,这样 anchor() 里就能省略锚名。

3 · 拖动试试:浮层自动跟随(零 JS 重算)

下面的锚可以拖动。注意:拖动只改了锚的 left/top,浮层的跟随完全由 CSS 计算——没有任何监听坐标、手动 reposition 的 JS。这正是与「JS 手算」的本质差别。

4 · 关键差别:无视 overflow、跨越包含块

同一个「藏在裁剪盒里的按钮」,左边用传统方案(tooltip 是盒子的子元素)被 overflow: clip 切掉了一半;右边用 anchor positioning——tooltip 是盒子外部的兄弟元素,却锚定盒子里面的按钮,完整显示、不受裁剪。

这就是「视觉对齐 ⟂ DOM 结构」。浮层不必再是锚的子孙(于是不受 overflow / transform / stacking 牵连),甚至能待在 top layer——它视觉上贴着谁和它在 DOM 中的位置已在很大程度上解耦。本系列其余页面都建立在这个基础上:popover 在 top layer、菜单置于 body,都照样精确对齐。

但不要理解成「真的放哪都行」。仍有两条约束:为保证可移植,应让锚先于浮层(顺序颠倒时在旧实现里会导致 anchor() 静默失败;新版 Chromium 已放宽,但不应依赖),且浮层的包含块要能包住锚。最稳妥的写法——兄弟、锚在前。细节见 「细节与边界」页