CSS Anchor Positioning 详解

多年来,定位工具提示、下拉菜单和弹出框意味着要与复杂的 JavaScript 计算作斗争。你需要测量元素、跟踪滚动位置,并不断重新计算以保持 UI 元素的正确对齐。CSS Anchor Positioning 通过让你使用纯 CSS 将元素相互附加来彻底改变这一点——无需 JavaScript。
关键要点
- CSS Anchor Positioning 实现了无需 JavaScript 计算的纯 CSS 元素定位
- 使用 anchor-name 和 position-anchor 在元素之间创建关系
- position-area 属性提供简单的基于网格的定位
- 内置的回退机制自动处理视口边缘情况
什么是 CSS Anchor Positioning?
CSS Anchor Positioning 是一个原生浏览器 API,允许你相对于页面上的其他元素来定位元素。可以将其视为在元素之间创建无形的连接:一个充当”锚点”(参考点),另一个充当”目标”(被定位的元素)。
这消除了在构建工具提示、上下文菜单和浮动对话框等常见 UI 模式时对 JavaScript 定位库的需求。浏览器处理所有复杂的计算,包括视口边界和滚动位置。
核心属性:构建锚点关系
使用 anchor-name 设置锚点
首先,你需要通过给元素一个唯一标识符来将其指定为锚点:
.menu-button {
anchor-name: --main-menu;
}
锚点名称必须以双破折号(--
)开头,类似于 CSS 自定义属性。
使用 position-anchor 连接元素
接下来,将目标元素连接到锚点:
.dropdown-menu {
position: absolute;
position-anchor: --main-menu;
}
目标元素必须具有 position: absolute
或 position: fixed
才能与锚点定位配合使用。
使用 position-area 定位元素
position-area
属性提供了定位目标的最简单方法。它使用以锚点为中心的 3×3 网格模型:
.dropdown-menu {
position: absolute;
position-anchor: --main-menu;
position-area: bottom center;
}
你可以使用物理值(top
、bottom
、left
、right
)或逻辑值(block-start
、inline-end
)以获得更好的国际化支持。span-
前缀允许元素跨越多个网格单元格:
.tooltip {
position-area: top span-inline;
}
Discover how at OpenReplay.com.
使用 anchor() 函数进行精细调整
要进行精确控制,请将 anchor()
函数与 inset 属性一起使用:
.tooltip {
position: absolute;
position-anchor: --trigger;
top: anchor(bottom);
left: anchor(left);
}
这将工具提示的顶部边缘定位在锚点的底部边缘,左边缘对齐。你也可以显式引用特定锚点:
.multi-anchor-target {
top: anchor(--anchor-1 bottom);
right: anchor(--anchor-2 left);
}
使用 anchor-size() 进行响应式尺寸调整
anchor-size()
函数允许你基于锚点的尺寸来调整元素大小:
.dynamic-tooltip {
position-anchor: --button;
width: anchor-size(width);
max-height: calc(anchor-size(height) * 2);
}
这创建了与锚点成比例缩放的工具提示——非常适合响应式设计。
使用 position-try 处理边缘情况
当你的定位元素碰到视口边缘时会发生什么?position-try
属性提供回退位置:
.context-menu {
position: absolute;
position-anchor: --menu-trigger;
position-area: bottom start;
position-try: flip-block, flip-inline;
}
当主要位置会导致溢出时,浏览器会自动尝试替代位置。内置关键字如 flip-block
和 flip-inline
处理常见场景,或者你可以定义自定义回退:
@position-try --compact-menu {
position-area: top;
width: 200px;
}
.context-menu {
position-try: --compact-menu, flip-block;
}
浏览器支持状态
截至 2024 年底,CSS Anchor Positioning 的浏览器支持正在增长:
- Chrome/Edge:自版本 125 起完全支持
- Safari:自版本 18 起支持
- Firefox:正在实现中
对于生产使用,考虑使用 Oddbird polyfill,它提供了对 Firefox 54 和 Chrome 51 的向后兼容性。功能检测很简单:
@supports (anchor-name: --test) {
/* Anchor positioning 样式 */
}
实际实现技巧
在为工具提示和菜单实现 CSS anchor positioning 时:
- 始终重置弹出元素的默认定位:
inset: auto
- 使用逻辑属性以获得更好的国际化支持
- 与 Popover API 结合使用,实现完全无 JavaScript 的交互
- 记住可访问性——添加适当的 ARIA 属性以维护语义关系
结论
CSS Anchor Positioning 改变了我们构建浮动 UI 元素的方式。通过将定位逻辑从 JavaScript 转移到 CSS,我们获得了更好的性能、更清洁的代码以及边缘情况的自动处理。在等待完整浏览器支持的同时,polyfill 为生产使用提供了可靠的前进路径。开始尝试工具提示和下拉菜单——你会很快欣赏声明关系而不是计算位置的简单性。
常见问题
是的,CSS Anchor Positioning 适用于动态创建的元素。只要正确设置了 anchor-name 和 position-anchor 属性,浏览器就会建立定位关系,无论元素何时添加到 DOM 中。
CSS Anchor Positioning 自动跟踪容器内的滚动位置。即使发生滚动,定位元素也会保持与锚点的关系,无需任何 JavaScript 事件监听器或手动重新计算位置。
当多个元素共享相同的 anchor-name 时,DOM 顺序中的最后一个元素成为活动锚点。这种行为可能导致意外的定位,因此最佳实践是为每个定位关系使用唯一的锚点名称。
是的,你可以使用标准的 CSS 过渡和动画为锚点定位的元素添加动画。在动画过程中锚点关系得以维护,并且 position-area 等属性可以在不同值之间平滑过渡,实现流畅的 UI 效果。
Truly understand users experience
See every user interaction, feel every frustration and track all hesitations with OpenReplay — the open-source digital experience platform. It can be self-hosted in minutes, giving you complete control over your customer data. . Check our GitHub repo and join the thousands of developers in our community..