transition(过渡)和 animation(动画)的区别是什么?
transition(过渡)和 animation(动画)都是 CSS3 中用于实现元素动态效果的属性,但它们的设计目的、控制粒度和使用场景有很大的区别。
简单来说:Transition 是“从 A 到 B 的平滑变化”,而 Animation 是“自导自演的复杂剧本”。
以下是它们的详细区别对比:
1. 核心区别总结
| 特性 | Transition (过渡) | Animation (动画) |
|---|---|---|
| 触发方式 | 被动触发。需要状态变化(如 :hover、:focus、JS 修改 class)才能启动。 |
主动触发。可以自动运行,也可以通过状态触发。 |
| 状态数量 | 只有两个状态:开始状态和结束状态。 | 多个状态:通过关键帧 (@keyframes) 定义任意数量的中间状态 (0% -> 50% -> 100%)。 |
| 循环能力 | 不能自动循环。通常运行一次就结束(除非反复触发)。 | 支持循环。可以设定无限循环 (infinite) 或指定次数。 |
| 控制能力 | 较弱。只能控制时长、延迟、缓动函数。 | 很强。可以暂停 (paused)、反向播放 (alternate)、保持结束状态 (forwards) 等。 |
| 复杂度 | 简单易用,代码少。 | 相对复杂,需要定义关键帧。 |
2. 详细解析
A. Transition (过渡)
它的核心逻辑是 “补间”。当元素的某个 CSS 属性值发生变化时,浏览器自动计算中间值,让变化过程变得平滑,而不是瞬间完成。
特点:
- 关注点: 状态 A 到 状态 B 的过程。
- 一次性: 触发一次,执行一次。
- 隐式: 你只需要定义起点和终点,中间怎么变由浏览器决定。
代码示例:
css.box { width: 100px; background: blue; /* 当 width 或 background 变化时,用 1秒钟平滑过渡 */ transition: all 1s ease-in-out; } .box:hover { width: 200px; /* 状态变化触发过渡 */ background: red; }
B. Animation (动画)
它的核心逻辑是 “时间轴”。它允许你通过 @keyframes 定义一个时间轴,并在时间轴的不同百分比位置设置不同的样式。
特点:
- 关注点: 整个过程的精细控制(关键帧)。
- 灵活性: 可以在 0% 是红色,50% 变绿色,100% 变黄色。
- 自动运行: 页面加载后即可自动播放,不需要鼠标滑过。
代码示例:
css/* 定义剧本 */ @keyframes bounce { 0% { transform: translateY(0); } 50% { transform: translateY(-20px); } 100% { transform: translateY(0); } } .ball { width: 50px; height: 50px; background: orange; border-radius: 50%; /* 调用剧本:无限循环,每次 1秒 */ animation: bounce 1s infinite; }
3. 什么时候用哪个?
使用 transition 的场景:
- 简单的交互反馈: 按钮的 Hover 变色、输入框 Focus 时边框变亮。
- 简单的状态切换: 侧边栏的展开/收起(宽度变化)、模态框的淡入淡出(Opacity 变化)。
- 只需要关注“开始”和“结束”两个状态时。
使用 animation 的场景:
- 复杂的加载动画: 旋转的 Loading 图标、跳动的进度条。
- 自动播放的效果: 轮播图的自动切换、页面进入时的元素飞入效果。
- 需要循环的效果: 心跳效果、闪烁的呼吸灯。
- 需要中间状态控制: 比如一个物体先向右走,再向下走,最后回到原点(多段路径)。
- 需要暂停或反向播放: 使用
animation-play-state: paused可以通过 JS 暂停动画。
4. 补充:性能方面
在性能优化上,两者没有本质区别。
- 无论是
transition还是animation,如果改变的是transform(位移、缩放、旋转) 或opacity(透明度),浏览器通常都会开启硬件加速(GPU),性能都很好。 - 如果改变的是
width、height、left、top等触发布局重排(Reflow)的属性,两者都会比较消耗性能。