CSS 入门教程
动画 animation
本教程共 44 篇 · 第 39 篇 · 更新于 2026-07-29 · 约 13 分钟阅读
动画animationkeyframes关键帧循环动画
39. 动画 animation
本节目标:掌握 @keyframes 关键帧动画,理解 animation 系列属性的作用,能够创建自动播放、循环、往返的复杂动画效果。
过渡需要状态变化触发,动画不需要。定义好运价规则,元素就能自动执行动画,甚至可以无限循环。
@keyframes:定义关键帧
动画的核心是 @keyframes 规则,它定义了动画过程中各阶段的样式。
@keyframes 动画名称 {
from { 起始样式 }
to { 结束样式 }
}
或者用百分比:
@keyframes 动画名称 {
0% { 起始样式 }
50% { 中间样式 }
100% { 结束样式 }
}
<!DOCTYPE html>
<html lang="zh">
<head>
<style>
@keyframes color-change {
from { background: #E74C3C; }
to { background: #3498DB; }
}
.box {
width: 100px;
height: 100px;
background: #E74C3C;
animation: color-change 2s;
}
</style>
</head>
<body>
<div class="box"></div>
</body>
</html>
animation-name 与 animation-duration
动画定义好后,需要绑定到元素上。animation-name 指定用哪个动画,animation-duration 指定持续时间。
.box {
animation-name: slide;
animation-duration: 3s;
}
如果只写
不写
duration,动画不会播放,因为默认时长是 0。
animation-iteration-count:播放次数
控制动画播放几次。
animation-iteration-count: 3; /* 播放 3 次 */
animation-iteration-count: infinite; /* 无限循环 */
<!DOCTYPE html>
<html lang="zh">
<head>
<style>
@keyframes pulse {
0%, 100% { transform: scale(1); }
50% { transform: scale(1.15); }
}
.dot {
width: 40px;
height: 40px;
background: #E74C3C;
border-radius: 50%;
animation: pulse 1s ease-in-out infinite;
margin: 40px;
}
</style>
</head>
<body>
<div class="dot"></div>
</body>
</html>
animation-direction:播放方向
控制动画的播放方向。
| 值 | 效果 |
|---|---|
normal | 正向播放(默认) |
reverse | 反向播放 |
alternate | 正向-反向-正向交替 |
alternate-reverse | 反向-正向-反向交替 |
<!DOCTYPE html>
<html lang="zh">
<head>
<style>
@keyframes bounce {
0% { transform: translateY(0); }
100% { transform: translateY(-30px); }
}
.ball {
width: 50px;
height: 50px;
background: #3498DB;
border-radius: 50%;
animation: bounce 0.5s ease-in-out infinite alternate;
margin: 50px;
}
</style>
</head>
<body>
<div class="ball"></div>
</body>
</html>
Tip是做往返动画的最佳选择。配合
infinite,一个关键帧就能做出平滑的来回效果。
animation-delay:延迟播放
动画开始前的等待时间。负值会让动画从中间开始播放。
animation-delay: 2s; /* 延迟 2 秒 */
animation-delay: -1s; /* 已经播放了 1 秒的状态开始 */
animation-fill-mode:填充模式
控制动画在播放前后,元素应用什么样式。
| 值 | 效果 |
|---|---|
none | 播放前后不应用任何关键帧样式 |
forwards | 保留最后一帧的样式 |
backwards | 应用第一帧的样式(延迟期间也有效) |
both | 同时遵循 forwards 和 backwards |
<!DOCTYPE html>
<html lang="zh">
<head>
<style>
@keyframes fade-in {
from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: translateY(0); }
}
.card {
width: 200px;
padding: 20px;
background: #2ECC71;
color: white;
border-radius: 8px;
opacity: 0; /* 初始不可见 */
animation: fade-in 0.6s ease-out 1s both;
/* both: 延迟期间用 from 样式(opacity:0),结束后保留 to 样式 */
}
</style>
</head>
<body>
<div class="card">1 秒后淡入</div>
</body>
</html>
做入场动画时,
非常常用。既保证延迟期间元素不可见,又保证结束后保持最终状态。
animation-play-state:暂停与运行
控制动画的播放状态。常用于悬停时暂停。
.box {
animation: spin 2s linear infinite;
}
.box:hover {
animation-play-state: paused;
}
<!DOCTYPE html>
<html lang="zh">
<head>
<style>
@keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
.spinner {
width: 60px;
height: 60px;
border: 4px solid #E0E0E0;
border-top-color: #3498DB;
border-radius: 50%;
animation: spin 1s linear infinite;
margin: 40px;
}
</style>
</head>
<body>
<div class="spinner" title="悬停暂停"></div>
</body>
</html>
animation-timing-function:速度曲线
和过渡一样,控制动画过程中的速度变化。
animation-timing-function: ease; /* 默认 */
animation-timing-function: steps(4); /* 分 4 步完成 */
animation-timing-function: cubic-bezier(0.68, -0.55, 0.27, 1.55); /* 回弹 */
Tip是做帧动画的关键。比如加载图标分成 8 帧,就用
steps(8)。
animation 简写属性
animation 按顺序包含:name、duration、timing-function、delay、iteration-count、direction、fill-mode、play-state。
/* 完整写法 */
animation: slide 3s ease-in-out 1s 2 alternate forwards;
/* 最少需要 name 和 duration */
animation: slide 3s;
<!DOCTYPE html>
<html lang="zh">
<head>
<style>
@keyframes loading {
0% { width: 0; background: #E74C3C; }
50% { width: 50%; background: #F39C12; }
100% { width: 100%; background: #2ECC71; }
}
.progress {
height: 8px;
background: #E74C3C;
border-radius: 4px;
animation: loading 3s ease-in-out forwards;
margin: 40px auto;
max-width: 400px;
}
</style>
</head>
<body>
<div class="progress"></div>
</body>
</html>
多个动画
一个元素可以同时应用多个动画,用逗号分隔:
.box {
animation: fade-in 1s ease-out, scale-up 0.5s ease-out 0.5s;
}
过渡 vs 动画
| 对比 | 过渡 | 动画 |
|---|---|---|
| 触发方式 | 需要状态变化 | 自动播放 |
| 关键帧 | 只有开始和结束 | 可以有多个 |
| 循环 | 不能 | 可以无限循环 |
| 适用场景 | 悬停、开关反馈 | 加载动画、持续动效 |
实际项目中,简单的状态变化用过渡,复杂的、需要循环的动效用动画。两者经常结合使用。
动画属性速查
| 属性 | 作用 | 默认值 |
|---|---|---|
animation-name | 动画名称 | none |
animation-duration | 动画时长 | 0s |
animation-timing-function | 速度曲线 | ease |
animation-delay | 延迟时间 | 0s |
animation-iteration-count | 播放次数 | 1 |
animation-direction | 播放方向 | normal |
animation-fill-mode | 填充模式 | none |
animation-play-state | 播放状态 | running |
animation | 简写 | — |