CSS3 动画终极教程:从入门到精通
CSS3 动画让网页元素能够以平滑、优雅的方式动起来,无需复杂的 JavaScript,它主要由两部分组成:

(图片来源网络,侵删)
- 过渡:用于实现元素状态(如颜色、位置、大小)的平滑变化。
- 动画:用于实现更复杂、多步骤、可控制的动画序列。
我们将从最简单的 transition 开始,逐步深入到功能强大的 @keyframes 动画。
第一部分:CSS 过渡 - 实现平滑的状态变化
过渡是 CSS3 动画的基础,它允许你为属性值的变化添加一个“缓动”效果。
核心概念
过渡效果由四个核心属性控制:
transition-property: 指定哪个 CSS 属性需要添加过渡效果(width,background-color,transform)。transition-duration: 指定过渡效果持续的时间(5s,1000ms)。transition-timing-function: 指定过渡的速度曲线,控制动画的节奏感。transition-delay: 指定过渡效果开始前的延迟时间。
为了方便,通常使用简写属性 transition。

(图片来源网络,侵删)
语法与示例
基本语法:
.element {
/* 简写形式: property duration timing-function delay */
transition: all 0.5s ease-in-out 0.2s;
/* 或者分开写 */
transition-property: width, background-color;
transition-duration: 0.5s;
transition-timing-function: ease-in-out;
transition-delay: 0.2s;
}
示例:一个简单的悬停效果
HTML:
<button class="hover-btn">悬停我</button>
CSS:

(图片来源网络,侵删)
.hover-btn {
padding: 15px 30px;
font-size: 16px;
background-color: #3498db;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
/* 初始状态,定义过渡 */
transition: background-color 0.3s ease, transform 0.3s ease;
}
/* 鼠标悬停时的目标状态 */
.hover-btn:hover {
background-color: #e74c3c;
transform: scale(1.05); /* 轻微放大 */
}
代码解析:
.hover-btn是元素的初始样式。transition属性告诉浏览器:当background-color和transform这两个属性发生变化时,要用3s的时间,以ease的速度曲线来平滑过渡。- 当鼠标移到
.hover-btn上时(hover伪类),它的background-color变成了红色,transform变成了scale(1.05)。 - 因为之前定义了
transition,所以这个变化不是瞬间完成的,而是持续了3s,从而产生了平滑的动画效果。
常用的 transition-timing-function
ease: 默认值,慢速开始,然后加快,最后变慢。linear: 匀速,从头到尾速度相同。ease-in: 慢速开始。ease-out: 慢速结束。ease-in-out: 慢速开始和结束,类似ease但更明显。cubic-bezier(n, n, n, n): 自定义贝塞尔曲线,可以创建非常独特的速度节奏。
第二部分:CSS 动画 - 创建复杂的多步动画
当简单的过渡无法满足需求时(想让元素弹跳、旋转多次、沿着复杂路径移动),就需要使用 @keyframes 动画。
核心概念
CSS 动画主要由两部分组成:
@keyframes规则:定义动画的各个阶段(关键帧),你告诉浏览器在动画的 0%、25%、50%、75%、100% 等时间点,元素应该是什么样子。- 动画属性:将
@keyframes应用到 HTML 元素上,并控制其行为。
@keyframes 规则
@keyframes 的名字可以自定义,用于后续引用。
@keyframes slideIn {
/* 动画开始时的状态 */
0% {
transform: translateX(-100%);
opacity: 0;
}
/* 动画 50% 时的状态 */
50% {
opacity: 1;
}
/* 动画结束时的状态 */
100% {
transform: translateX(0);
opacity: 1;
}
}
动画属性
将定义好的动画应用到元素上:
animation-name: 指定要引用的@keyframes的名字。animation-duration: 指定动画完成一次所需的时间。animation-timing-function: 指定动画的速度曲线。animation-delay: 指定动画开始前的延迟。animation-iteration-count: 指定动画播放的次数,可以是数字(如2),或者infinite(无限循环)。animation-direction: 指定动画的播放方向。normal: 默认,正常播放。reverse: 反向播放。alternate: 轮换播放(第1次正常,第2次反向...)。alternate-reverse: 轮换反向播放(第1次反向,第2次正常...)。
animation-fill-mode: 指定动画结束后的状态。none: 默认,动画结束后回到原始状态。forwards: 动画结束后,保持最后一帧的状态。backwards: 动画开始前,保持第一帧的状态(在delay期间有效)。both: 同时应用forwards和backwards。
同样,也存在一个简写属性 animation。
综合示例:一个弹跳的盒子
HTML:
<div class="box"></div>
CSS:
.box {
width: 100px;
height: 100px;
background-color: #9b59b6;
margin: 50px;
}
/* 1. 定义关键帧动画 */
@keyframes bounce {
0%, 20%, 50%, 80%, 100% {
transform: translateY(0);
}
40% {
transform: translateY(-30px);
}
60% {
transform: translateY(-15px);
}
}
/* 2. 将动画应用到元素上 */
.box {
animation-name: bounce;
animation-duration: 1.5s;
animation-timing-function: ease;
animation-iteration-count: infinite;
/* 使用简写属性 */
animation: bounce 1.5s ease infinite;
}
代码解析:
- 我们定义了一个名为
bounce的动画,在0%,20%,50%,80%,100%这些时间点,盒子都在原始位置(translateY(0)),在40%时,它向上移动-30px,在60%时,它向上移动-15px,这样就形成了弹跳的效果。 - 我们使用
animation简写属性,将bounce动画应用到.box元素上,让它持续5s,以ease的节奏,无限循环 (infinite) 播放。
第三部分:进阶技巧与最佳实践
transform 和 opacity 的性能优势
在进行动画时,尽量优先使用 transform (如 translate, scale, rotate) 和 opacity 属性。
为什么?
现代浏览器对这两个属性有专门的优化,它们不会触发页面的重排,只会触发重绘,性能开销远小于改变 width, height, margin, left 等会触发重排的属性。
性能优化前 (不推荐):
.box {
width: 100px;
animation: grow 1s ease infinite;
}
@keyframes grow {
100% { width: 200px; }
}
性能优化后 (推荐):
.box {
width: 100px;
animation: grow 1s ease infinite;
}
@keyframes grow {
100% { transform: scale(2); }
}
动画触发
默认情况下,CSS 动画在页面加载后就会自动开始,如果想在某个特定事件(如点击、悬停)后触发动画,可以结合 hover 或 JavaScript 来控制。
示例:点击后触发动画
HTML:
<div class="click-box"></div>
CSS:
.click-box {
width: 100px;
height: 100px;
background-color: #1abc9c;
/* 初始状态,动画未播放 */
animation: none; /* 或者直接不写 animation */
}
.click-box.animate {
animation: spin 1s ease;
}
@keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
JavaScript:
document.querySelector('.click-box').addEventListener('click', function() {
this.classList.add('animate');
// 如果想每次点击都重新播放,需要先移除再添加
// this.addEventListener('animationend', function() {
// this.classList.remove('animate');
// });
});
动画事件
你可以使用 JavaScript 监听动画的关键事件,从而执行更复杂的逻辑。
animationstart: 动画开始时触发。animationend: 动画结束时触发。animationiteration: 每次动画循环一次时触发(仅对iteration-count > 1有效)。
const box = document.querySelector('.click-box');
box.addEventListener('animationstart', () => {
console.log('动画开始了!');
});
box.addEventListener('animationend', () => {
console.log('动画结束了!');
});
box.addEventListener('animationiteration', () => {
console.log('动画完成了一次循环!');
});
第四部分:总结与对比
| 特性 | CSS transition |
CSS @keyframes animation |
|---|---|---|
| 控制能力 | 简单,只能在两个状态间过渡 | 强大,可以定义多个关键帧 |
| 触发方式 | 通常由用户交互(如 hover)或脚本改变样式触发 |
页面加载后自动开始,或通过脚本类名触发 |
| 关键帧 | 无 | 有 (@keyframes) |
| 循环次数 | 需要通过 JavaScript 循环类名来实现 | 内置 iteration-count 属性(infinite) |
| 方向控制 | 无 | 内置 direction 属性 |
| 结束状态 | 返回原始状态 | 可通过 fill-mode 控制保持结束状态 |
| 适用场景 | 简单的悬停效果、按钮反馈、淡入淡出 | 复杂的序列动画、加载动画、Logo动效 |
学习资源推荐
- MDN Web Docs: CSS Transitions 和 CSS Animations 是最权威、最详细的参考资料。
- CSS-Tricks: 有大量关于 CSS 动画的实用文章和技巧。
- CodePen / JSFiddle: 在线代码编辑器,你可以看到无数优秀的动画实例,并直接修改代码进行学习。
希望这份教程能帮助你系统地掌握 CSS3 动画!动手实践是学习的最好方式,快去创建属于你自己的酷炫动画吧!
