应避免使用transition: all,因其会触发重排和重绘、兼容性差且失控;正确做法是明确指定background-color、transform等可合成属性,并配以0.25s ease或cubic-bezier缓动函数。

transition: all 会偷偷触发重排和重绘
写了 transition: all 0.3s,鼠标一 hover,按钮卡顿、文字模糊、阴影闪烁——这不是你电脑慢,是浏览器被迫对 width、height、margin、box-shadow 等一堆属性做插值计算。其中 width 和 height 变化会强制触发 layout(重排),box-shadow 和 filter 则引发 paint(重绘),这两类操作都在主线程跑,帧率直接掉到 30fps 以下。
更隐蔽的问题是:JS 框架或第三方库可能在你不知情时修改了 padding 或 font-size,all 就会立刻响应,导致过渡意外重播或跳变。
all 在旧浏览器里根本不管用 transform 和 opacity
Safari 12 之前、部分 Android WebView 对 transition: all 的解析不一致:transform 和 opacity 常被忽略,结果就是缩放或淡入直接“啪”一下跳过去,毫无过渡。这不是 bug,是规范实现差异——浏览器只对它认为“安全可插值”的属性启用 all,而这些恰恰是你最想动的 GPU 加速属性。
- 写
transition: transform 0.25s, opacity 0.25s,所有现代浏览器都稳 - 写
transition: all 0.25s,Safari 11 下transform不动,Chrome 却正常——调试时很难复现
all 让你失去控制权,连禁用都难
你想临时关掉过渡?写 transition: none 没用,它不是合法值;写 transition-duration: 0s 也不保险,某些设备仍有微弱动画。真正有效的只有 transition-property: none,但它和 all 共存时行为不可预测——不同浏览器可能优先解析 all 或直接丢弃整条规则。
另外,Tailwind 的 transition-all 类如果和 will-change: transform 同时存在,图层缓存反而被破坏,性能比不用还差。
替代方案很简单:只列你要动的属性
明确写出你要过渡的属性名,哪怕多敲几个字:
button {
transition: background-color 0.25s ease, transform 0.25s cubic-bezier(0.4, 0, 0.2, 1);
}
button:hover {
background-color: #0056b3;
transform: scale(1.05);
}
这样做的好处:
-
background-color和transform都是合成属性,走 GPU,不重排不重绘 - 每个属性可配独立缓动函数,比如缩放用
cubic-bezier(0.4, 0, 0.2, 1),颜色用ease - 删掉某一项(比如去掉
transform)就立刻停掉对应动画,无副作用
真正麻烦的从来不是写法本身,而是把决策权交给 all 后,你再也无法确定哪一帧在重排、哪一行 JS 触发了意外过渡。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











