CSS动画与过渡
# 05.CSS动画与过渡
transition 平滑过渡、animation 与 @keyframes 关键帧动画、贝塞尔缓动函数、will-change 与 GPU 加速、动画性能优化四项法则。
# 1. transition — 属性平滑过渡
.box {
background: blue;
transition: background 0.3s ease;
}
.box:hover {
background: red; /* 0.3s 内从蓝渐变到红 */
}
# 1.1 完整语法
/* transition: property duration timing-function delay */
transition: all 0.3s ease 0s;
/* 分别写 */
transition-property: background, transform;
transition-duration: 0.3s, 0.5s; /* 不同属性不同时长 */
transition-timing-function: ease, linear;
transition-delay: 0s, 0.1s; /* 延迟触发 */
可过渡的属性(必须是可插值的数值型):
✅ 可以过渡:
opacity, color, background-color, transform,
width, height, margin, padding, border-width,
left, right, top, bottom, font-size, line-height
❌ 不能过渡:
display, visibility(只用0/1跳变), background-image,
font-family, position, float, z-index(整数跳变)
# 1.2 timing-function 缓动
transition-timing-function: ease; /* 默认:慢→快→慢 */
transition-timing-function: linear; /* 匀速 */
transition-timing-function: ease-in; /* 慢→快 */
transition-timing-function: ease-out; /* 快→慢 */
transition-timing-function: ease-in-out; /* 慢→快→慢 */
/* 自定义贝塞尔曲线 */
transition-timing-function: cubic-bezier(0.25, 0.1, 0.25, 1.0);
/* 常用回弹效果 */
transition-timing-function: cubic-bezier(0.68, -0.55, 0.27, 1.55);
| 场景 | 推荐缓动 |
|---|---|
| 按钮 hover | ease-out (0.2s) |
| 模态框弹出 | cubic-bezier(0,0,0.2,1)(类似 ease-out 更强) |
| 列表滑入 | ease-out + 逐项递增 delay |
| 进度条 | linear |
# 2. animation + @keyframes — 关键帧动画
/* 定义动画 */
@keyframes slideIn {
from { transform: translateX(-100%); opacity: 0; }
to { transform: translateX(0); opacity: 1; }
}
/* 或按百分比 */
@keyframes pulse {
0%, 100% { transform: scale(1); }
50% { transform: scale(1.1); }
}
/* 使用动画 */
.element {
animation: slideIn 0.5s ease-out;
}
# 2.1 完整语法
/* animation: name duration timing-function delay iteration-count direction fill-mode play-state */
animation: slideIn 0.5s ease-out 0s 1 normal forwards;
/* 拆开写 */
animation-name: slideIn;
animation-duration: 0.5s;
animation-timing-function: ease-out;
animation-delay: 0.2s;
animation-iteration-count: infinite; /* 无限循环,或指定次数 */
animation-direction: alternate; /* 正向播放后反向 */
animation-fill-mode: forwards; /* 结束后保持最后帧 */
animation-play-state: paused; /* 暂停 */
# 2.2 fill-mode — 动画前后状态
| 值 | 动画前 | 动画后 |
|---|---|---|
none | 原始样式 | 回到原始样式 |
forwards | 原始样式 | 保持最后一帧 |
backwards | 应用第一帧(delay 期间) | 回到原始 |
both | 应用第一帧 | 保持最后一帧 |
/* 常见需求:动画结束后停留 */
.enter { animation: fadeIn 0.3s both; }
.exit { animation: fadeOut 0.3s forwards; }
# 2.3 实用动画库
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
@keyframes slideUp {
from { transform: translateY(20px); opacity: 0; }
to { transform: translateY(0); opacity: 1; }
}
@keyframes spin {
to { transform: rotate(360deg); }
}
@keyframes shimmer {
0% { background-position: -200% 0; }
100% { background-position: 200% 0; }
}
/* 骨架屏闪烁 */
.skeleton {
background: linear-gradient(90deg, #eee 25%, #f5f5f5 50%, #eee 75%);
background-size: 200% 100%;
animation: shimmer 1.5s infinite;
}
# 3. GPU 加速与 will-change
# 3.1 哪些属性触发 GPU 合成
只改变 transform 和 opacity 可以跳过重排和重绘,直接走 GPU 合成层:
/* ✅ 仅触发合成(最高性能) */
transform: translateX(100px);
transform: scale(1.1);
transform: rotate(45deg);
opacity: 0.5;
/* ⚠️ 触发重绘(次高性能) */
color: red;
background: blue;
/* ❌ 触发重排(最差性能) */
width: 200px; /* 重排 */
left: 100px; /* 重排 */
margin-top: 20px; /* 重排 */
# 3.2 will-change — 提前通知浏览器
/* 告诉浏览器"这个元素即将有 transform 动画",提前提升为合成层 */
.card {
will-change: transform;
}
.card:hover {
transform: scale(1.05); /* 已提前 GPU 加速,动画流畅 */
}
使用原则:
- 在动画之前设置,动画结束后移除
- 不要给大量元素同时设置(每个合成层都消耗 GPU 显存)
- 优先用在交互反馈(hover/click),而非页面加载
# 4. 动画性能四项法则
法则 1:动画只改 transform 和 opacity
→ 跳过重排/重绘,直接 GPU 合成
法则 2:用 transform 代替 position 移动
❌ left: 100px → 触发重排
✅ translateX(100px) → 仅合成
法则 3:用 scale 代替 width/height 动画
❌ width: 200px → 触发重排
✅ transform: scale(1.5) → 仅合成
法则 4:避免在动画中读取布局属性
❌ 动画回调中读 offsetWidth/offsetHeight → 强制同步重排
# 5. 实战:骨架屏 + 列表交错动画
/* 交错延迟入场 */
.list-item {
opacity: 0;
animation: slideUp 0.4s ease-out forwards;
}
.list-item:nth-child(1) { animation-delay: 0.05s; }
.list-item:nth-child(2) { animation-delay: 0.10s; }
.list-item:nth-child(3) { animation-delay: 0.15s; }
/* ... */
# 6. 速查表
| 需求 | 方案 |
|---|---|
| 按钮 hover 变色 | transition: background 0.2s |
| 模态框淡入 | @keyframes fadeIn + animation: fadeIn 0.3s both |
| 无限旋转加载 | @keyframes spin + animation: spin 1s linear infinite |
| 性能优先的移动动画 | transform: translateX() 而非 left |
| 提前告之浏览器即将动画 | will-change: transform |
| 动画暂停/恢复 | animation-play-state: paused / running |
下一篇:06.响应式布局实战 — 媒体查询、rem/vw、容器查询、6 种居中、经典布局方案。
上次更新: 2026/06/24, 10:13:05