零重排显隐通过 scale 和 opacity 实现,因二者属合成层属性,仅触发 Composite 阶段;需配合 visibility 控制、transform-origin 声明及 translateZ(0) 硬件加速。

用 scale 和 opacity 实现零重排显隐,核心是避开所有触发布局计算的属性(如 display、width、height、left、top),只依赖 GPU 加速的合成层属性。
为什么能零重排?
transform: scale() 和 opacity 都属于“仅影响绘制层”的属性,浏览器会把它们提升到独立的合成层(compositing layer),动画过程中不触发布局(Layout)和绘制(Paint),只做合成(Composite)——这就是零重排的关键。
对比来看:
– display: none 会让元素退出渲染树,强制重排;
– visibility: hidden 虽保留布局,但无法过渡;
– opacity: 0 + transform: scale(0.95) 则全程在合成层内变化,无重排无重绘。
基础写法:transition 方案
适合开关式显隐(如点击弹窗显示/隐藏):
- 初始状态设为
opacity: 0; transform: scale(0.95); visibility: hidden; - 显隐切换靠 class 控制,比如
.is-open -
transition必须写在同一声明里:
transition: opacity 0.25s cubic-bezier(0.25, 0.46, 0.45, 0.94), transform 0.25s cubic-bezier(0.25, 0.46, 0.45, 0.94); - 显开时设
visibility: visible; opacity: 1; transform: scale(1);(注意visibility: visible是触发动画的“开关”,不能漏)
@keyframes 动画方案
适合更精细控制入场节奏(如模态框从远端缩放进入):
立即学习“前端免费学习笔记(深入)”;
- 起始帧不要用
scale(0),推荐scale(0.8)或scale(0.95),避免内容渲染异常或点击失效 - 必须搭配
animation-fill-mode: forwards,确保动画结束后保持终态样式 - 示例关键帧:
@keyframes fadeScaleIn { from { opacity: 0; transform: scale(0.95); } to { opacity: 1; transform: scale(1); } }应用时加
animation: fadeScaleIn 0.3s ease-out forwards;
配套细节不能少
光有 scale 和 opacity 不够,还需三项配合:
-
定位方式:模态框等浮层建议用
position: fixed或absolute,脱离文档流,避免 scale 挤压周围元素 -
缩放原点:显式写
transform-origin: center(即使默认也是 center,也建议声明,防止被继承覆盖) -
硬件加速:iOS Safari 等环境可能出现缩放模糊,可加
transform: scale(1) translateZ(0)强制启用 GPU 加速


















