图片淡入淡出卡顿主因是 opacity 动画被 layout/paint 干扰,应通过 will-change: opacity、transform: translateZ(0) 或 scale(1) 触发硬件加速,隔离合成图层,并避免过渡 all 或读取 offsetHeight 等强制重排操作。
用 transition: opacity 做图片淡入淡出时出现“卡顿”或“不平滑”,通常不是 opacity 本身的问题,而是触发了非合成(non-composite)属性重排,或者浏览器没走硬件加速路径。关键在让 opacity 动画跑在独立图层上。
如果图片的父容器或自身有频繁变化的布局属性(比如 width、height、margin、padding、top/left 等),哪怕只是 JS 里读取 offsetHeight,都可能打断 opacity 的流畅性。opacity 本该只触发“合成”,但一旦混入 layout 或 paint 阶段,帧率就会掉。
offsetTop、getBoundingClientRect() 等强制同步 layout 的 APIwill-change: opacity(仅在需要时,别滥用)让浏览器把图片单独拎进一个合成层(compositing layer),能极大提升 opacity 动画的稳定性。
transform: translateZ(0) 或 transform: scale(1)(更轻量)backface-visibility: hidden(兼容性更好)transform: will-change-transform + will-change: opacity,但注意只对即将动画的元素设置看似简单,但细节影响体验:
transition: opacity 0.3s ease-in-out,别写成 all 0.3s —— 否则其他属性变更也会被强行过渡cubic-bezier(0.25, 0.46, 0.45, 0.94)(类似 iOS 淡入),比纯 e
ase 更自然常见“隐形杀手”:
overflow: hidden 且图片有 transform,可能截断图层提升,导致闪烁或降级回 CPU 渲染filter: blur() 或 drop-shadow(),会阻止合成优化(除非也加上 transform 提升)prefers-reduced-motion: reduce,部分浏览器会禁用 transition —— 可加媒体查询兜底:@media (prefers-reduced-motion: reduce) { * { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; } }