你以为浮层定位只能靠库?CSS 今天用三个属性把这件事彻底原生化了
每次写 tooltip 都要先装一个库,这件事到 2026 年终于结束了。
用过 Popper.js 或者它的继任者 Floating UI 的工程师大概都有一个同感:给一个按钮配个浮层提示,明明是个 UI 问题,却要写一整段 JavaScript——getBoundingClientRect 算坐标、ResizeObserver 监听变化、flip 中间件处理边界溢出。一套下来三十行,装完依赖再加十几 KB。
CSS Anchor Positioning 把这件事从根上原生化了。
核心就三个属性。给触发元素挂一个名字:
.trigger {
anchor-name: –my-tooltip;
}
给浮层元素绑定到这个名字,然后用 position-area 指定位置:
.tooltip {
position: absolute;
position-anchor: –my-tooltip;
position-area: top; / 浏览器自动选 9 宫格里的最优位置 /
margin-top: 8px;
}
position-area 替代了 Floating UI 的 flip 中间件——浏览器自己会判断空间够不够,不够就自动翻到对面去,不需要你写一行判断逻辑。
想要更精确的控制,用 anchor() 函数直接读锚点的边缘:
.tooltip {
position: absolute;
position-anchor: –my-tooltip;
top: anchor(bottom); / 浮层顶边对齐触发元素底边 /
left: anchor(center); / 水平居中 /
transform: translateX(-50%);
margin-top: 8px;
}
anchor-size(width) 替代了 getBoundingClientRect().width——让下拉框自动和触发按钮等宽:
.dropdown {
position: absolute;
position-anchor: –menu-btn;
position-area: block-end span-inline;
min-inline-size: anchor-size(inline); / 宽度等于锚点宽度,一行 /
}
视口边界翻转,一行替代几十行 flip 中间件:
.tooltip {
position-try-fallbacks: flip-block; / 自动向上翻 if 空间不够 /
}
这是 position-try-fallbacks,不是旧名 position-try-options(Chrome 125–128 用旧名,新版都迁移了)。
性能差距是结构性的。Floating UI 的 computePosition() 在主线程微任务队列里跑,每次滚动触发重新算账。CSS Anchor Positioning 跑在浏览器的合成器线程,GPU 直接算坐标,主线程零干预。实测 50 个 tooltip 的页面,用 Popper.js 滚动有明显 jank,切到 CSS Anchor 之后中档手机也流畅。
库体积归零。Popper.js + 依赖:15–20 KB gzipped。Floating UI:8–12 KB。CSS Anchor Positioning:0 KB。这些字节不只省了下载时间,还省了 parse 和 execution 对 TTI 和 INP 的影响。
当前浏览器覆盖。Chrome 125+、Firefox 147+(2026 年 1 月进入 Baseline)、Safari 26+。全球约 92%。Safari 18.2–18.3 还不支持 @position-try,但 anchor() 和 position-anchor 本身是支持的——写 tooltip 位置的时候把 base position 放在 @position-try 外面,Safari 照常显示,只是没有自动翻转。
什么时候还要保留 Floating UI。三个场景:虚拟元素(tooltip 挂载在 DOM 外,比如图表的 canvas 上)、位置切换动画(从「上方」平滑过渡到「右侧」的动画过程)、必须兼容 2024 年前的旧浏览器而且不想写 @supports 兜底。
下一步。如果你的项目还在装 Floating UI,先用 @supports (anchor-name: –test) 做渐进增强,然后按 tooltip → dropdown → popover 的顺序逐个迁移。每迁移一个组件,删掉一行 import,删掉一个 useFloating hook,删掉一段 scroll 监听——这是 2026 年前端工程化最直接的「做减法」。
评论区
登录后可评论。