transition本身不实现动画,而是对可过渡属性变化进行插值计算;平滑与否取决于是否选用opacity、transform等合成属性,配合合理timing函数及硬件加速。

直接说结论:transition 本身不“实现动画”,它只是告诉浏览器:当某个可过渡的 CSS 属性值变化时,用指定方式“插值计算中间帧”——是否平滑,取决于你选的属性、timing 函数和是否触发了合成层。
哪些 CSS 属性能真正平滑过渡
不是所有属性改了都能过渡出“视觉平滑”效果。浏览器只对部分属性做了插值支持,且性能差异极大:
-
opacity、transform(如translate、scale、rotate)是首选:它们走合成层,不触发布局重排(Reflow)和重绘(Repaint),帧率稳定 -
width、height、margin、padding、background-color等能过渡,但会触发 Layout + Paint,小元素还行,大区域或高频变化容易卡顿 -
display、z-index、font-size(非数值单位时)等根本不能过渡——改了就立刻生效,transition对它们完全无效
transition 的写法陷阱:简写 vs 分开写
用简写 transition: all 0.3s ease; 看似省事,实际埋雷:
- 一旦元素上任何可过渡属性意外变化(比如 JS 改了
opacity又顺手改了border-color),全都会被拖进同一段过渡,节奏混乱 -
all在某些旧版 Safari 中会把本不该动的属性也卷进来,比如box-shadow的模糊半径突变导致闪烁 - 推荐明确锁定:例如
transition: transform 0.25s cubic-bezier(0.34, 1.56, 0.64, 1), opacity 0.2s ease;—— 只动该动的,且允许不同属性用不同持续时间和曲线
为什么 hover 动画有时“卡一下”才开始
常见现象:鼠标移上去,元素停顿约 100ms 才动。这通常不是 transition-delay 导致的,而是以下原因:
- 初始状态没设
transform:比如只写了.btn:hover { transform: scale(1.1); },但正常态没定义transform: scale(1);,浏览器要从none插值到scale(1.1),部分引擎处理慢 - CSS 选择器权重不足:hover 类被其他规则覆盖,实际样式没生效,直到重绘时机才“追上”
- 未启用硬件加速:在
transform值后加translateZ(0)或will-change: transform(慎用),可主动提示浏览器升层,但别滥用,否则内存开销明显
timing-function 不是调参游戏,得看场景
cubic-bezier 很酷,但多数情况没必要手调。记住几个真实有效的组合:
- 按钮反馈、图标缩放:用
ease-out—— 快进慢出,符合物理惯性,用户感知更“跟手” - 加载占位、骨架屏淡入:用
ease-in—— 慢起快收,避免“突然弹出来”的突兀感 - 开关切换、状态翻转(开/关):用
linear—— 匀速最中性,不带情绪,适合功能型交互 - Chrome DevTools 里点
ease旁的小图标可实时拖拽贝塞尔曲线,但上线前务必在真机上验证——移动端 touch 响应延迟会让某些曲线显得“粘滞”
真正难的不是写对 transition,而是判断该不该用它:状态变化是否足够简单?是否需要精确控制每一帧?要不要支持中断与反向?这些边界问题,往往比语法本身更决定最终体验是否“平滑”。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











