弹窗居中的代码拢共没几行,打开瞬间却总往旁边挪一下 🪟。居中是好的,位置也对,就是会跳。折腾半天,祸首竟然是滚动条。把排查过程记一笔。

祸首:滚动条显隐
弹窗打开时给 body 加 overflow: hidden 锁滚动,滚动条一消失,视口立刻变宽十几像素。用 left 50% 定位的弹窗,基准变了,位置自然跳 📏。
解法一行:
html { scrollbar-gutter: stable; }
滚动条位置常年预留,显隐不再引起宽度变化。
次犯:定位与动画方式
居中用 margin 负值或动画改宽高,每一帧都在触发重排,抖动感就这么来的。换成 transform 就稳了:
.dialog { position: fixed; left: 50%; top: 50%;
transform: translate(-50%, -50%); }
translate 走合成层,动画期间位置稳如磐石 ✅。
帮凶:两个细节
- fixed 弹窗被放进局部滚动容器,祖先再有 transform,定位基准直接跑偏。弹窗挂到 body 直下最省心 ⚠️。
- 动画循环里反复
getBoundingClientRect(),每次都强制同步布局,帧率与位置一起抖。读一次缓存起来用。
结论:抖动不是居中的锅,是布局基准在变。scrollbar-gutter 占位、transform 居中、弹窗挂顶层,三件事做完,世界安静了。
