transition没生效需检查三处硬性条件:属性值必须可动画、状态切换必须触发重绘、元素不能被浏览器降级为软件渲染。

transition没生效?先查这三处硬性条件
transition不是写了就一定动,它有三个刚性前提:属性值必须可动画、状态切换必须触发重绘、元素不能被浏览器降级为软件渲染。常见失效场景包括:display: none → block 切换(display 不可动画)、visibility: hidden → visible(不触发重绘)、父容器 overflow: hidden 导致子元素 transform 被强制回退到 CPU 渲染。
实操建议:
立即学习“前端免费学习笔记(深入)”;
- 用 DevTools 的 “Computed” 面板确认目标属性是否出现在
transition解析结果里,而不是只看 Styles 面板里的声明 - 在触发状态变化后,手动执行
getComputedStyle(el).transform或el.offsetHeight强制触发重排,验证是否真有样式变更 - 对关键动画元素启用
transform: translate3d(0, 0, 0),再检查 Rendering 面板的 “Layer borders” 是否出现独立图层
旧浏览器卡顿,别只改缓动函数
IE11、Android 4.4 WebView、Safari 9 等环境里,卡顿主因不是 cubic-bezier() 写错,而是过渡根本没进 GPU 合成通道。这些引擎对简写 transition: all .3s 解析极脆弱,稍有覆盖就丢帧。
实操建议:
立即学习“前端免费学习笔记(深入)”;
- 每个需动画的元素,单独写完整声明:
transition: transform 0.3s cubic-bezier(.25,.46,.45,.94), opacity 0.3s ease;,避免继承或媒体查询中覆盖 - 慎用
will-change:IE11 完全忽略,Android 4.4 可能闪烁;改用backface-visibility: hidden更稳 - JS 动态加 class 后立刻改
style.transform,必须等上一帧结束——用requestAnimationFrame(() => { el.style.transform = '...' })
滚动中 background-color 过渡掉帧?换思路
滚动监听 + background-color 过渡看似合理,但实际极易掉帧:每次 scroll 事件触发都可能引发 layout thrashing,尤其当页面有 offsetHeight 读取或伪元素参与时。
实操建议:
立即学习“前端免费学习笔记(深入)”;
- 放弃直接监听
scroll改背景色,改用IntersectionObserver检测滚动位置阈值,减少回调频率 - 把颜色变化拆解为两层:固定背景层(
background-color)+ 浮动蒙版层(opacity过渡),后者只动 GPU 友好属性 - 若必须 JS 控制,用
requestAnimationFrame批量写样式,且确保所有读操作(如getBoundingClientRect())放在下一帧
伪元素动画抖动?定位和触发时机是关键
::before / ::after 本身不响应事件,动画靠父元素状态驱动。但很多人忽略:伪元素若未脱离文档流,transform 动画会拖拽整个布局重新计算,尤其在 flex/grid 容器中。
实操建议:
立即学习“前端免费学习笔记(深入)”;
- 父元素必须设
position: relative,伪元素用position: absolute定位,彻底脱离流 -
transition必须定义在默认状态(非:hover),否则离开时无动画 - 避免用
left/top做位移,改用transform: translateX();若需缩放,优先transform: scaleX()而非width
transform 动画,父容器加了 filter: blur(1px) 就足以让它退回 CPU 渲染;又比如 transitionend 在 iOS Safari 9–10 中可能丢失,不加 setTimeout 兜底清理临时 class,会导致内存泄漏或后续动画错乱。


















