transition、animation 和 transform 有什么区别?
简化版
transition 描述状态变化之间的过渡,通常需要触发条件;animation 通过 @keyframes 定义一段可自动播放的动画;transform 是变换属性,可做位移、缩放、旋转,常因不触发布局而更适合高性能动画。
详细版
三者分工不同:
transition:从旧状态平滑过渡到新状态,适合 hover、展开收起。animation:按关键帧播放,适合循环、复杂节奏、自动播放。transform:改变元素视觉位置或形态,不改变文档流占位。
高性能动画通常优先使用 transform 和 opacity。
如果动画频繁改变 width、height、top、left,可能触发布局计算,成本更高。
完整版教学
一、transition 是状态变化的补间
transition 本身不定义“去哪儿”。
它定义的是某个 CSS 属性从旧值变到新值时,过渡多久、怎么过渡。
所以它通常依赖 hover、class 切换、媒体查询变化等触发。
.button {
opacity: 0.6;
transition: opacity 200ms ease;
}
.button:hover {
opacity: 1;
}
这里状态变化只有 1 个属性:opacity 从 0.6 到 1。
transition 负责把瞬间变化拉长到 200ms。
如果没有状态变化,transition 不会凭空播放动画。
二、animation 是关键帧驱动的时间线
animation 通过 @keyframes 定义多个时间点的样式。
它可以自动播放、循环播放、延迟播放,也可以控制方向和填充模式。
适合比“两个状态之间过渡”更复杂的动画。
@keyframes pulse {
0% { transform: scale(1); }
50% { transform: scale(1.08); }
100% { transform: scale(1); }
}
.badge {
animation: pulse 1.2s ease-in-out infinite;
}
这个动画在 1.2s 内经历 3 个关键点。
如果要循环提醒、骨架屏闪动、加载状态,animation 比反复切 class 更自然。
三、transform 改变视觉,不改变文档流占位
transform 可以做平移、缩放、旋转、倾斜。
它改变的是元素的视觉呈现,不会影响普通文档流中的原始占位。
因此一个元素 translateX(100px) 后,旁边元素不会因为它移动而重新排版。
.card {
transform: translateX(100px) scale(1.1);
}
流程可以这样看:
布局阶段确定原始盒子位置
-> 绘制阶段画出元素
-> 合成阶段应用 transform
这也是 transform 常被推荐用于动画的原因。
它通常可以减少布局和绘制压力,更容易由合成线程处理。
四、为什么 transform 和 opacity 动画更流畅
浏览器渲染大致包括样式计算、布局、绘制、合成。
改变 width、height、top、left 往往会影响布局。
改变 transform、opacity 通常不需要重新布局。
| 动画属性 | 常见影响 | 性能风险 |
|---|---|---|
width/height | 布局 + 绘制 + 合成 | 高 |
top/left | 可能触发布局 | 中高 |
background-color | 绘制 + 合成 | 中 |
transform | 多数走合成 | 低 |
opacity | 多数走合成 | 低 |
例如 60fps 动画每帧只有约 16.7ms。
如果每帧都触发布局和大面积绘制,很容易掉帧。
所以面试里提到性能,要优先答 transform 和 opacity。
五、三者经常组合使用
transition 可以过渡 transform。
animation 也可以在关键帧里改变 transform。
所以三者不是互斥关系,而是不同层次的概念。
.drawer {
transform: translateX(-100%);
transition: transform 300ms ease;
}
.drawer.open {
transform: translateX(0);
}
这个抽屉例子中:
transform 定义位置变化,transition 定义变化过程。
如果要抽屉打开后持续呼吸闪烁,再加 animation 也可以。
记忆钩子:
transform是变什么,transition是两个状态怎么过渡,animation是按时间线怎么演。
六、工程注意:动画不是越多越好
动画会影响性能、可访问性和用户注意力。
对关键交互,动画应短、稳、可预期。
对大面积动画,要考虑 prefers-reduced-motion,尊重用户减少动态效果的系统设置。
@media (prefers-reduced-motion: reduce) {
* {
animation-duration: 0.01ms !important;
transition-duration: 0.01ms !important;
}
}
另外不要滥用 will-change。
它可以提示浏览器提前优化,但过多使用会占用内存。
只应在确实即将发生动画的元素上短期使用。
七、常见误区与追问
- 误区:transition 会自动播放动画。 transition 需要属性值发生变化,才会产生过渡。
- 误区:transform 会改变元素原本占位。 transform 改变视觉呈现,不改变普通文档流中的占位。
- 误区:所有 CSS 动画都很流畅。 改变布局属性可能触发布局和绘制,性能不一定好。
- 追问:为什么推荐 transform 代替 top/left 做位移? transform 多数情况下不触发布局,更容易走合成,掉帧风险更低。
- 追问:animation 和 transition 怎么选? 两个状态过渡用 transition,多关键帧、循环或自动播放用 animation。
- 追问:
will-change能不能全局加? 不建议,过度提升图层会增加内存和合成成本。
八、加强记忆
把三者放到一句结构里:transform 定义视觉变换,transition 平滑两个状态之间的变化,animation 用关键帧组织一条时间线。回答性能时记住 60fps 每帧约 16.7ms,优先选择 transform/opacity,谨慎动画布局属性。