介绍
在 Web 开发中,相对于特定参考元素(锚点)定位浮动元素(例如工具提示、弹出窗口、下拉菜单和悬停卡)历来是一项复杂的挑战。
为了使浮动元素在窗口大小调整或页面滚动时跟随锚点,开发人员传统上依靠连续的 JavaScript 坐标计算(使用 getBoundingClientRect())来动态更改内联样式。因此,像 Popper.js 或 Floating UI 这样的库成为了行业标准。但是,在滚动事件期间在主线程上执行脚本循环经常会导致渲染延迟和卡顿,尤其是在移动设备上。
CSS 锚定位 API 通过在浏览器中本地处理浮动坐标来解决这些缺点。在本指南中,我们将探讨该标准的核心功能并逐步介绍实用的 UI 配方。
1.什么是CSS锚点定位?
CSS 锚定位是一种原生样式标准,可让您完全使用 CSS 将绝对或固定位置元素(目标)直接锚定到另一个元素(锚)。
核心优势
- 零 JavaScript: 消除了对调整大小侦听器、滚动事件观察器和自定义坐标计算逻辑的需要。
- 卓越的性能: 位置更新和渲染直接卸载到浏览器的合成器线程,以 60+ FPS 渲染流畅的视觉更新。
- 布局隔离: 绝对或固定目标元素可以绕过父边界剪切约束(例如
overflow: hidden),尤其是与 HTML<dialog>元素或本机popover属性配对时。
2. 基本设置和语法
让我们看一下将工具提示容器绑定到按钮元素的基本设置。
HTML结构
我们声明一个锚元素(按钮)及其目标浮动容器(div)。
<button class="my-anchor">Hover over me</button>
<div class="my-tooltip">This is a native CSS tooltip</div>
CSS 实现
为了在 CSS 中将元素联系在一起,我们遵循三个步骤:
- 在引用锚元素上声明唯一的
anchor-name标识符。 - 定义
position: absolute并在目标上使用position-anchor引用标识符。 - 通过
anchor()定位功能对齐坐标。
/* 1. Set up the Anchor */
.my-anchor {
/* Anchor names must be formatted as dashed identifiers, similar to CSS custom properties */
anchor-name: --anchor-button;
}
/* 2 & 3. Format the Target */
.my-tooltip {
position: absolute;
position-anchor: --anchor-button;
/* Pin the top of the tooltip to the bottom boundary of the anchor button */
top: anchor(bottom);
/* Place the horizontal center of the tooltip to the center of the anchor */
left: anchor(center);
transform: translateX(-50%);
/* Styling defaults */
background: #333;
color: #fff;
padding: 8px;
border-radius: 4px;
}
只需几行 CSS,工具提示就可以直接捕捉到按钮下方。即使用户滚动文档,布局引擎也会自动更新位置。
3. 使用位置尝试处理边缘约束
浮动组件的一个主要问题是视口边缘的裁剪。如果锚点按钮位于屏幕底部附近,则将工具提示放置在其下方会强制其离开屏幕。
CSS 锚点定位使用 position-try-fallbacks 动态处理视口碰撞。
.my-tooltip {
position: absolute;
position-anchor: --anchor-button;
/* Preferred placement */
top: anchor(bottom);
left: anchor(center);
transform: translateX(-50%);
/* Define fallback positions when default bounds collide with viewport edges */
position-try-fallbacks: flip-block, flip-inline;
}
flip-block: 如果没有足够的空间,则自动翻转垂直对齐(例如,将工具提示放置在锚点上方而不是下方)。flip-inline: 如果工具提示被左或右视口边界切断,则移动水平位置。
您还可以使用 @position-try 指令编写自定义布局:
@position-try --top-layout {
bottom: anchor(top);
top: auto;
left: anchor(center);
}
4. 与 Popover API 完美配合
当与 HTML5 Popover API(popover 属性) 配合使用时,CSS 锚点定位变得异常强大。
Popover API 允许您将元素推送到文档堆栈的顶层,而无需使用 JS。然而,由于顶层元素存在于常规文档布局流程之外,因此将它们锚定在常规按钮旁边过去很困难。
锚定定位弥补了这一差距:
<!-- Interactive Popover Hook -->
<button class="menu-btn" popovertarget="my-menu" style="anchor-name: --menu-anchor;">
Open Menu
</button>
<div popover id="my-menu" style="
position: absolute;
position-anchor: --menu-anchor;
top: anchor(bottom);
left: anchor(left);
margin: 0;
">
<ul>
<li>Dashboard</li>
<li>Settings</li>
<li>Log out</li>
</ul>
</div>
通过这种模式,可以创建一个完全可访问的下拉菜单,该菜单位于所有溢出上方并与触发按钮的坐标相匹配,而无需导入任何 JavaScript 依赖项。
结论和浏览器支持
Chromium 引擎(Chrome、Edge、Opera)完全支持 CSS 锚点定位。 Safari 和 Firefox 的实施和讨论正在迅速进展。
对于需要跨旧版浏览器即时支持的生产代码库,可以使用官方的 CSS 锚定位 Polyfill。
通过迁移到本机 CSS 锚点定位,减少应用程序包大小、加速帧渲染并简化组件样式。

