必须加 transform: translateZ(0) 触发 GPU 加速,否则 opacity 动画在旧版 Safari 和 Android WebView 中易闪烁卡顿;禁用 display: none/visibility: hidden,改用 opacity + pointer-events 控制显隐。

animation + opacity 实现页面切换淡入,必须加 transform: translateZ(0)
单纯用 opacity 配合 animation 做淡入,在部分浏览器(尤其是旧版 Safari 和 Android WebView)会出现闪烁、掉帧或动画卡顿。根本原因是 opacity 动画没触发硬件加速,浏览器仍在用 CPU 做合成。
解决办法是强制开启 GPU 加速,最轻量且兼容性好的写法是加一个不影响布局的 transform: translateZ(0):
/* 正确写法:触发硬件加速 */
.fade-in {
opacity: 0;
animation: fadeIn 0.3s ease-out forwards;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateZ(0); }
to { opacity: 1; transform: translateZ(0); }
}- 不要只写
opacity动画,不加transform属性 —— iOS 15 之前 Safari 极大概率闪屏 -
translateZ(0)比translate3d(0,0,0)更轻量,语义更清晰,两者效果一致 - 如果页面已有其他 transform(比如 rotate 或 scale),无需重复加
translateZ(0),但得确保它出现在 keyframes 里
页面切换时 opacity 动画失效?检查 display: none / visibility: hidden
常见错误是:在淡入前把元素设为 display: none,或者用 visibility: hidden 配合 opacity: 0 —— 这会导致 @keyframes 根本不执行,因为元素已脱离渲染流或被隐藏锁定。
正确做法是让元素始终处于渲染树中,仅靠 opacity 控制可见性:
立即学习“前端免费学习笔记(深入)”;
- 初始状态用
opacity: 0; pointer-events: none;(避免点击穿透) - 绝对不要用
display: none切换状态,改用opacity+pointer-events组合 - 如果必须用 JS 控制显隐,用
element.style.opacity = '0'替代element.style.display = 'none' -
visibility: hidden会阻止动画触发,除非先设成visibility: visible再开动画
transition 和 animation 哪个更适合页面切换?
用 transition 更简单,但只适合「有明确触发状态变化」的场景(比如路由切换后 class 切换);animation 更可控,适合需要精确时序、延迟、循环或 JS 主动触发的流程。
实际项目中推荐这样选:
- 单页应用(SPA)路由切换:用
transition+ class 切换,性能好、代码少 - 需要 JS 控制淡入时机(比如数据加载完再显示):用
animation,配合animation-play-state或 JS 的element.animate() - 要兼容 IE10+:避开
element.animate(),坚持用 CSS@keyframes+ class 切换 - 避免混用:不要一边写
transition: opacity,一边又用animation控制同一元素的opacity,行为不可预测
opacity 动画在 Safari 上跳帧?别用 cubic-bezier(.1,.9,.2,1)
Safari 对某些高精度 cubic-bezier() 缓动函数支持不稳定,尤其 cubic-bezier(.1,.9,.2,1) 这类“慢入快出”曲线,在 iOS 14–16 上容易导致第一帧直接跳到 0.3 透明度,破坏淡入感。
稳妥方案是用系统级关键词或简化参数:
- 优先用
ease-out,它在所有浏览器中表现一致 - 如需自定义,改用
cubic-bezier(0.25, 0.46, 0.45, 0.94)(Framer Motion 默认值,Safari 兼容性好) - 避免小数点后两位以上,比如
.178改成.18,Safari 解析更稳定 - 动画时长别低于 0.2s —— iOS 上
0.15s容易被系统截断成单帧
页面切换淡入看着简单,真正上线后最容易栽在 Safari 的渲染策略和旧安卓 WebView 的合成逻辑上。opacity 不是万能钥匙,得配对 transform、绕开 display、盯紧缓动函数——这些不是细节,是动画能跑起来的前提。


















