应使用transform/opacity替代left/top/width等非合成属性动画,因iOS Safari(15.4–16.6)对后者强制软件渲染导致卡顿闪烁;需配合backface-visibility: hidden(写在动画元素自身、紧接transform后)、真机验证图层合成。

用 transform/opacity 替代 left/top/width 动画
iOS Safari(15.4–16.6)对非合成属性做 transition 会强制走软件渲染,视觉上就是卡顿或闪烁。这不是 bug,是 WebKit 的设计:它只对 transform 和 opacity 这类属性默认启用 GPU 合成。
错误写法:.box { left: -100px; transition: left 0.3s; } —— 触发重排,必闪。
正确写法应改用位移变换:.box { transform: translateX(-100px); transition: transform 0.3s; }
- 所有位移动画优先用
translateX/translateY,别碰top/left - 显隐控制用
opacity+visibility,不用display: none - 背景色过渡若必须,可套一层伪元素,用
opacity控制其遮罩层
给动画元素加 backface-visibility: hidden
这个声明不是开启 GPU 加速的开关,而是告诉 WebKit:“请为我单独建一个稳定图层”。但它只在满足三个硬条件时才生效:
立即学习“前端免费学习笔记(深入)”;
- 必须写在「正在动画的元素本身」上,比如
.slide-item { backface-visibility: hidden; }—— 加在父容器上完全无效 - 必须紧接在
transform声明之后,且transform不能是none或空值;推荐写法:transform: translateZ(0); backface-visibility: hidden; - 如果元素真要做翻转(如
rotateY(180deg)),背面需显示,则必须设为visible,否则内容消失
漏掉任一条件,backface-visibility: hidden 就白加。
规划您的迪拜之旅 — 哈利法塔观景、沙漠探险、迪拜购物中心购物、棕榈岛度假村及黄金市场砍价。还提供支持...
避免把 transition 只写在 .dark-theme 类里
深色模式切换时闪屏,往往是因为 transition 没写在基础状态中。浏览器看到的是“从无过渡 → 突然换色”,根本来不及插值。
错误写法:body.dark-theme { background-color: #121212; transition: background-color 0.3s; }
正确做法是把 transition 提前写在初始规则里:body { background-color: #ffffff; transition: background-color 0.3s; }
- 所有带过渡的颜色、透明度等属性,都要在默认状态下声明
transition - 变量切换要用类名(如
.dark-theme)而非直接setProperty,否则 Safari 来不及同步新值进渲染流水线 -
var(--bg)必须带 fallback:background-color: var(--bg, #ffffff)
真机测试比 DevTools 准得多
桌面 Safari 的 Layers 面板显示成层,不等于 iPhone 上也成层。很多闪烁只在 iOS 真机上出现,尤其首次动画或页面滚动后。
务必在真机上打开 Safari Web Inspector → Layers 面板,确认目标元素是否真的出现在 “Composited Layers” 列表中——没出现,说明它根本没被 GPU 加速,加什么都白搭。
另外,iOS 微信、QQ 等 WebView 内核往往比系统 Safari 更老,要单独测;系统开了“减少动画”会进一步退化合成行为,测试前务必关闭。

















