Back

CSS Anchor Positioning 详解

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: absoluteposition: fixed 才能与锚点定位配合使用。

使用 position-area 定位元素

position-area 属性提供了定位目标的最简单方法。它使用以锚点为中心的 3×3 网格模型:

.dropdown-menu {
  position: absolute;
  position-anchor: --main-menu;
  position-area: bottom center;
}

你可以使用物理值(topbottomleftright)或逻辑值(block-startinline-end)以获得更好的国际化支持。span- 前缀允许元素跨越多个网格单元格:

.tooltip {
  position-area: top span-inline;
}

使用 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-blockflip-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 时:

  1. 始终重置弹出元素的默认定位:inset: auto
  2. 使用逻辑属性以获得更好的国际化支持
  3. 与 Popover API 结合使用,实现完全无 JavaScript 的交互
  4. 记住可访问性——添加适当的 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..

OpenReplay