🎬 CSS 动画总览
理解 CSS 动画的两种实现方式
CSS 动画的两种实现方式
CSS 提供了两种创建动画的方式:Transition(过渡) 和 Animation(动画)。 它们都可以让 CSS 属性的变化变得平滑,但适用场景不同。
重要:Transition 和 Animation 都可以动画任何 CSS 属性(transform、opacity、color、width 等), 不是只能用于 transform。Transform 只是一个常用的动画属性。
⚠️ 核心理解:CSS 属性的变化默认是瞬间的
任何 CSS 属性的变化,默认都是瞬间完成的,没有动画过程。 这包括 transform、width、opacity、color、background 等所有属性。
/* ❌ 单独改变属性 - 瞬间变化,无动画 */
/* transform 单独使用 */
.box {
transform: rotate(0deg);
}
.box:hover {
transform: rotate(45deg); /* 立即旋转,无动画 */
}
/* width 单独使用 */
.box {
width: 100px;
}
.box:hover {
width: 200px; /* 立即变宽,无动画 */
}
/* opacity 单独使用 */
.box {
opacity: 1;
}
.box:hover {
opacity: 0.5; /* 立即变透明,无动画 */
}
/* background 单独使用 */
.box {
background: red;
}
.box:hover {
background: blue; /* 立即变色,无动画 */
}
如果想要平滑的动画效果,必须配合 Transition 或 Animation 使用。
/* ✅ 配合 transition - 平滑过渡 */
.box {
width: 100px;
opacity: 1;
background: red;
transition: all 0.3s ease; /* 添加过渡效果 */
}
.box:hover {
width: 200px; /* 0.3 秒内平滑变宽 */
opacity: 0.5; /* 0.3 秒内平滑变透明 */
background: blue; /* 0.3 秒内平滑变色 */
}
⚡ Transition(过渡)- 简单的状态变化
作用:让 CSS 属性的变化变得平滑,需要触发条件(如 :hover、:focus、JavaScript 改变类名)。
特点:只有开始和结束两个状态,简单易用,适合交互效果。
完整写法
/* 所有属性分开写 */
.box {
transition-property: transform; /* 要过渡的属性 */
transition-duration: 0.3s; /* 持续时间 */
transition-timing-function: ease; /* 缓动函数 */
transition-delay: 0s; /* 延迟时间 */
}
简写语法
/* 语法:transition: property duration timing-function delay; */
/* 完整简写 */
.box {
transition: transform 0.3s ease 0s; /* 属性 时长 缓动 延迟 */
}
/* 常用简写(省略延迟,默认 0s)*/
.box {
transition: transform 0.3s ease;
}
/* 最简写法(省略缓动,默认 ease)*/
.box {
transition: transform 0.3s;
}
/* 过渡所有属性 */
.box {
transition: all 0.3s ease; /* ↑ 所有可动画的属性都会过渡 */
}
多个属性分别设置
/* 不同属性使用不同的过渡效果 */
.box {
transition: transform 0.3s ease,
opacity 0.5s linear,
background 0.2s ease-in;
}
实际应用示例
/* 按钮悬停效果 */
.button {
transform: translateY(0);
transition: transform 0.2s ease;
}
.button:hover {
transform: translateY(-3px);
}
/* 卡片悬停效果 */
.card {
transition: all 0.3s ease;
}
.card:hover {
transform: translateY(-5px);
box-shadow: 0 10px 20px rgba(0,0,0,0.1);
}
可以过渡的属性:transform、opacity、color、background、width、height、margin、padding 等大部分 CSS 属性。
🎬 Animation(动画)- 复杂的关键帧动画
作用:创建复杂的、可重复的动画效果,必须配合 @keyframes 使用。
特点:可以有多个中间状态,可以自动播放、循环播放,更强大灵活。
第一步:定义关键帧
/* 使用 from/to */
@keyframes slideIn {
from {
transform: translateX(-100%);
}
to {
transform: translateX(0);
}
}
/* 使用百分比(更灵活)*/
@keyframes bounce {
0% {
transform: translateY(0);
}
50% {
transform: translateY(-30px);
}
100% {
transform: translateY(0);
}
}
第二步:完整写法
/* 所有属性分开写 */
.box {
animation-name: slideIn; /* 动画名称(@keyframes 定义的)*/
animation-duration: 1s; /* 持续时间 */
animation-timing-function: ease; /* 缓动函数 */
animation-delay: 0s; /* 延迟时间 */
animation-iteration-count: 1; /* 播放次数(1 或 infinite)*/
animation-direction: normal; /* 播放方向 */
animation-fill-mode: none; /* 填充模式 */
animation-play-state: running; /* 播放状态 */
}
简写语法
/* 语法:animation: name duration timing-function delay iteration-count direction fill-mode; */
/* 完整简写 */
.box {
animation: slideIn 1s ease 0s 1 normal none;
/* 名称 时长 缓动 延迟 次数 方向 填充 */
}
/* 常用简写(省略延迟、方向、填充)*/
.box {
animation: slideIn 1s ease;
}
/* 最简写法(省略缓动,默认 ease)*/
.box {
animation: slideIn 1s;
}
常用场景
/* 无限循环 */
.spinner {
animation: spin 2s linear infinite; /* ↑ 无限循环 */
}
/* 保持最后一帧 */
.fade-in {
animation: fadeIn 1s ease forwards; /* ↑ 结束后保持最后状态 */
}
/* 延迟 + 保持 */
.slide-in {
animation: slideIn 0.5s ease 0.3s 1 normal forwards;
/* ↑延迟0.3秒 ↑保持最后状态 */
}
/* 来回播放 */
.pulse {
animation: pulse 1s ease-in-out infinite alternate; /* ↑ 来回交替 */
}
实际应用示例
/* 加载动画 */
@keyframes spin {
to {
transform: rotate(360deg);
}
}
.loader {
animation: spin 1s linear infinite;
}
/* 页面加载淡入 */
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
.page {
animation: fadeIn 0.5s ease;
}
📊 Transition vs Animation 对比
| 特性 | Transition(过渡) | Animation(动画) |
|---|---|---|
| 定义方式 | 直接在元素上 | 需要 @keyframes |
| 触发方式 | 需要状态变化(:hover、JS 等) | 自动播放 |
| 状态数量 | 2 个(开始 → 结束) | 多个(0%, 25%, 50%, 100%...) |
| 循环播放 | ❌ 不支持 | ✅ 支持(infinite) |
| 可用属性 | 任何可动画的 CSS 属性 | 任何可动画的 CSS 属性 |
| 复杂度 | 简单 | 复杂 |
| 使用场景 | 悬停效果、简单交互 | 加载动画、复杂动画 |
🎯 Transform 的角色
Transform 是一个 CSS 属性,不是动画方式!它可以单独使用,也可以配合 Transition 或 Animation 使用。
三种使用方式对比
❌ 单独使用
有效果,但瞬间变化,无动画过程
✅ 配合 Transition
有平滑过渡,需要触发条件
✅ 配合 Animation
有复杂动画,可自动播放
代码对比
/* 方式 1:单独使用 transform - 瞬间变化 ❌ */
.box1 {
transform: rotate(45deg); /* 页面加载时立即旋转 45 度,无动画 */
}
.box1:hover {
transform: rotate(90deg); /* 悬停时立即旋转到 90 度,无动画 */
}
/* 方式 2:transform + transition - 平滑过渡 ✅ */
.box2 {
transform: rotate(0deg);
transition: transform 0.5s ease; /* 添加过渡效果 */
}
.box2:hover {
transform: rotate(45deg); /* 悬停时在 0.5 秒内平滑旋转到 45 度 */
}
/* 方式 3:transform + animation - 持续动画 ✅ */
@keyframes spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
.box3 {
animation: spin 2s linear infinite; /* 持续旋转,每圈 2 秒 */
}
📝 总结
- Transform 单独使用 = 有效果,但瞬间完成(没有动画过程)
- Transform + Transition = 有平滑的过渡动画
- Transform + Animation = 有复杂的关键帧动画
📐 是否影响文档流?
重要概念:Transition 和 Animation 本身不是变换,它们只是让属性变化变得平滑。 是否影响文档流,取决于你动画的是什么属性。
Transform - 永远不影响文档流 ✅
/* Transform 只是视觉变化,不影响布局 */
.box {
transform: translate(100px, 100px);
/* 元素视觉上移动了,但原来的空间仍然占据 */
/* 不会影响其他元素的布局 */
}
属性分类对比
| 属性类型 | 是否影响文档流 | 示例 | 性能 |
|---|---|---|---|
| Transform | ❌ 不影响 | translate, rotate, scale, skew | ⚡ 最佳(仅合成) |
| Opacity | ❌ 不影响 | opacity | ⚡ 最佳(仅合成) |
| Filter | ❌ 不影响 | blur, brightness, contrast | ⚡ 最佳(仅合成) |
| 盒模型 | ✅ 影响 | width, height, margin, padding | ⚠️ 差(触发重排) |
| 定位 | ✅ 影响 | top, left, right, bottom | ⚠️ 差(触发重排) |
| 颜色 | ❌ 不影响 | color, background-color, border-color | ⚡ 好(仅重绘) |
代码示例对比
/* ✅ 不影响文档流 - 动画 transform */
.box {
transition: transform 0.3s;
}
.box:hover {
transform: translateX(100px); /* 只是视觉变化 */
}
/* ✅ 不影响文档流 - 动画 opacity */
.box {
transition: opacity 0.3s;
}
.box:hover {
opacity: 0.5; /* 只是透明度变化 */
}
/* ❌ 影响文档流 - 动画 width */
.box {
transition: width 0.3s;
}
.box:hover {
width: 200px; /* 会影响其他元素的位置! */
}
/* ❌ 影响文档流 - 动画 margin */
.box {
transition: margin 0.3s;
}
.box:hover {
margin-left: 50px; /* 会影响其他元素的位置! */
}
⚡ 性能最佳实践
为了性能和避免布局抖动,推荐只动画这些属性:
- transform - 平移、旋转、缩放、倾斜
- opacity - 透明度
- filter - 滤镜效果
这些属性只触发合成(Composite),不会触发重排(Reflow)或重绘(Repaint),性能最好。
/* ✅ 推荐:高性能动画 */
.box {
transition: transform 0.3s, opacity 0.3s;
}
/* ❌ 避免:会触发重排,性能差 */
.box {
transition: width 0.3s, height 0.3s, margin 0.3s;
}
💡 如何选择?
- 使用 Transition:当你需要简单的状态变化,如按钮悬停、卡片展开等
- 使用 Animation:当你需要复杂的动画,如加载动画、页面进入动画、循环动画等
- 单独使用 Transform:当你只需要静态的变换效果,不需要动画过程
记住:
- Transition 和 Animation 都可以动画任何 CSS 属性,不只是 transform
- Transform 可以单独使用,但没有动画过程,是瞬间变化的
- 如果想要平滑的动画效果,需要配合 Transition 或 Animation
- Transform 永远不影响文档流,是否影响文档流取决于动画的属性
- 推荐只动画 transform、opacity、filter,性能最好