CSS: 动画 @keyframes
最后更新:2026-10-13
过渡(transition)只能处理"从状态 A 到状态 B"的简单变化。而通过 @keyframes(关键帧动画),你可以定义更复杂的多阶段动画——元素可以经过多个中间状态,甚至无限循环。
动画属性速查表
| 属性 | 常用值 | 作用 |
|---|---|---|
@keyframes |
动画名称 { 0% {...} 100% {...} } |
定义关键帧动画序列 |
animation-name |
fadeIn, slideLeft |
引用的 @keyframes 名称 |
animation-duration |
2s, 500ms |
动画完成一次的时间 |
animation-timing-function |
ease, linear, ease-in-out |
动画速度曲线 |
animation-delay |
0.5s, -1s(提前开始) |
动画开始前的延迟 |
animation-iteration-count |
1, 3, infinite |
动画播放次数 |
animation-direction |
normal, reverse, alternate, alternate-reverse |
动画方向 |
animation-fill-mode |
none, forwards, backwards, both |
动画结束后样式保持 |
animation-play-state |
running, paused |
动画播放/暂停状态 |
animation |
fadeIn 2s ease 0.5s infinite |
简写属性 |
1. @keyframes 定义动画
基本语法:
▶ 示例
▶ 试一试也可以使用 from 和 to 关键字(等价于 0% 和 100%):
▶ 示例
▶ 试一试(1) 多阶段动画
▶ 示例
▶ 试一试2. animation 属性
⚠️ animation 兼容性: 大部分现代浏览器已全面支持 CSS 动画,但
@keyframes 中的某些属性(如 auto 值)在某些浏览器上有兼容问题。复杂动画建议用 infinite 循环时加 alternate 让动画来回播放,比直接重复更自然。
定义好动画后,用 animation 属性应用到元素上:
(1) animation-name(动画名称)
▶ 示例
▶ 试一试(2) animation-duration(持续时间)
▶ 示例
▶ 试一试(3) animation-timing-function(速度曲线)
▶ 示例
▶ 试一试(4) animation-delay(延迟时间)
▶ 示例
▶ 试一试(5) animation-iteration-count(播放次数)
▶ 示例
▶ 试一试(6) animation-direction(方向)
▶ 示例
▶ 试一试(7) animation-fill-mode(填充模式)
控制动画开始前和结束后元素的样式:
▶ 示例
▶ 试一试(8) animation-play-state(播放状态)
▶ 示例
▶ 试一试(9) animation 简写
▶ 示例
▶ 试一试3. 综合示例
(1) 心跳动画
▶ 示例
▶ 试一试(2) 加载旋转动画
▶ 示例
▶ 试一试(3) 淡入滑入动画
▶ 示例
▶ 试一试(4) 逐帧动画
▶ 示例
▶ 试一试4. 动画性能优化
🔥 性能警告: 动画不要做太多。同时播放二三十个元素的动画会导致页面卡顿。用
will-change 属性提前告知浏览器哪些元素会有动画,但别滥用——设了 will-change 的元素会占用额外的 GPU 内存。
为了获得流畅的动画,尽量使用以下属性:
✅ 性能好的属性:
⚠️ 性能一般的属性:
❌ 尽量避免动画的属性:
width、height、margin、padding(会引起重排)box-shadow(计算开销大)
❓ 常见问题
Q @keyframes 和 transition 有什么区别?
A transition 只能处理"从状态 A 到状态 B"的简单变化,而 @keyframes 可以定义多个关键帧(0%、50%、100%),实现更复杂的多阶段动画。简单悬浮效果用 transition,复杂动效用 @keyframes。
Q animation 的 infinite 循环会让页面卡顿吗?
A 合理使用不会。但不要同时让太多元素做动画(建议不超过 20 个)。可以用 will-change 提前告诉浏览器哪些元素会变化,帮助 GPU 加速。如果页面掉帧,减少动画元素数量或缩短动画时长。
Q 动画结束后元素会跳回原位怎么办?
A 设置
animation-fill-mode: forwards,动画结束后会保持在最后一帧的状态。默认值是 none,动画播放完就回到起始位置。5. 实战案例:纯CSS轮播图
这个案例展示了如何用纯CSS实现一个简单的图片轮播效果,无需JavaScript:
▶ 示例
💡 实现原理: 使用
@keyframes 定义滑动动画,通过 translateX 控制轮播位置。每张幻灯片停留3秒,过渡0.3秒,循环播放。
📖 小节
@keyframes动画比transition更强大,可以定义多阶段的动画序列- 通过
animation属性的各个子属性,你可以控制动画的播放次数、方向、延迟、填充模式等 - 建议在动画中优先使用
transform和opacity以获得最佳性能 - 对于无限循环的动画(如加载旋转),记得用
infinite
📝 作业
- 创建一个"弹跳球"动画——球从空中掉落,触底反弹,逐渐减弱(使用 keyframes 的多阶段定义)。
- 制作一个"旋转加载器"——一个圆环不断旋转(提示:border + border-top-color + border-radius + animation)。
- 创建一个"渐入滑入"的页面:页面加载时,标题从上方滑入,段落从下方滑入,图片从左方滑入(使用不同的动画)。
- 制作一个"呼吸灯"按钮——按钮亮暗循环变化。