按钮缩放一下 tooltip 就飘走了——Safari 27 把 anchor 定位的 transform 感知彻底修好了
按钮缩放了一下,tooltip 就飘到了十万八千里外——这不是你的 CSS 写错了,是 Safari 27 之前 anchor positioning 根本「看不懂」transform。
Safari 27 修了这个问题。
CSS Anchor Positioning 让 tooltip、popover、注解这类浮动元素锚定到页面任意一个「锚点」上,不再需要 getBoundingClientRect()。用法很简单:锚点元素声明 anchor-name: --x,浮动元素声明 position-anchor: --x 并用 anchor() 函数读锚点边缘。这套机制在 Chrome 125+、Safari 18+ 就已经支持,Firefox 147+ 也在跟进。
但有一个坑,所有人踩了两年都不知道。
当锚点元素带了 CSS transform——比如一个 hover 时 scale(1.1) 的按钮——tooltip 的定位会「漂移」。原因是浏览器的布局引擎在计算锚点位置时,参考的是 transform 变换前的布局框,而不是视觉上的当前位置。换句话说:锚点明明「看」起来在这里,但浏览器认为它还在那里。
来看一个具体场景:
.card {
position: relative;
display: grid;
place-items: center;
gap: 1rem;
}
.card button {
anchor-name: --info-btn;
}
.card .tooltip {
position: absolute;
position-anchor: --info-btn;
position-area: top center;
margin-block-end: 0.5rem;
}
<div class="card">
<button style="transform: scale(1.1);">i</button>
<div class="tooltip" role="tooltip">更多信息</div>
</div>
Chrome 144+ 之前的 tooltip 会认为按钮还在 scale(1.0) 的位置,于是 tooltip 偏下;Safari 27 修了,tooltip 正确跟随按钮当前的视觉位置。
怎么检测浏览器是否支持「感知 transform 的锚点定位」?
这正是 @supports named-feature() 的用武之地。这个函数不是检测某个 CSS 属性存不存在,而是检测某种特定行为有没有实现:
/* 渐进增强:先写 fallback */
.tooltip {
position: absolute;
top: 0;
left: 50%;
transform: translateX(-50%);
}
/* 支持感知 transform 的锚点定位时,覆盖 fallback */
@supports (anchor-name: --x) and (position-anchor: --x) {
.tooltip-trigger { anchor-name: --info-btn; }
.tooltip {
position: absolute;
position-anchor: --info-btn;
position-area: top center;
margin-block-end: 0.5rem;
top: auto;
left: auto;
transform: none;
}
}
@supports named-feature(anchor-position-follows-transforms) 这个关键字在 Chrome 150+、Firefox 156+、Safari Technology Preview 中可用。Safari 27 正式版本身已经内置了完整的 transform-aware 锚点定位。
这次修复的根源很有意思:WebKit 团队在修复 Safari 27 一个 dialog 内锚点定位在页面滚动后失效的 bug 时,发现这个「transform 感知缺失」其实是同一批代码里的一个遗留问题,修复 dialog 的过程中一并把 transform 感知也修进去了。提交记录里写着:「原来 tracking transformed anchors 的逻辑一直都在,只是没被正确暴露」。
落地的时候注意什么?
目前 Firefox 156 还不支持 anchor-position-follows-transforms 这个关键字本身(虽然基础锚点定位已经支持)。所以渐进增强的策略是:
@supports (anchor-name: --x) {
.tooltip-trigger { anchor-name: --x; }
.tooltip {
position-anchor: --x;
position-area: top center;
}
}
/* transform 感知增强(仅 Chrome 144+ Safari 27+) */
@supports named-feature(anchor-position-follows-transforms) {
.tooltip-trigger:hover {
transform: scale(1.05); /* 现在 tooltip 会正确跟随 */
}
}
transform 只影响视觉,不影响布局流向——也就是说,即使 tooltip 因为浏览器不支持 transform-aware 锚点定位而位置偏了一点,页面本身的排版不会乱,只是 tooltip 视觉上「歪」了。这是对用户体验影响相对可控的一类 bug,用渐进增强来兜底是合理的。
如果你已经在项目里用了 anchor positioning,给 hover/active 状态的 transform 加上 @supports named-feature() 检测,让支持的浏览器获得更准的 tooltip 定位,不支持的保持原样——这是最低成本的升级路径。
评论区
登录后可评论。