第八章 · 8.3 节
animation 与 @keyframes
transition 只能描述"从一个状态到另一个状态"的两点式过渡,而 animation 配合 @keyframes 可以定义任意数量的中间关键帧,还能无限循环、自动播放,无需任何交互触发——适合加载动画、注意力引导等场景。
与 transition 的区别
| transition | animation | |
|---|---|---|
| 触发方式 | 需要状态变化触发(如 :hover) | 可自动播放,无需交互 |
| 关键帧数量 | 仅 2 个端点 | 任意多个(0%–100% 之间自由插入) |
| 循环 | 不支持 | 支持 infinite 等循环次数控制 |
定义 @keyframes
@keyframes pulse { 0% { transform: scale(1); opacity: 1; } 50% { transform: scale(1.08); opacity: .85; } 100% { transform: scale(1); opacity: 1; } }
百分比代表动画时间轴上的进度节点,也可以用 from / to 分别代替 0% / 100%。
animation 子属性
| 属性 | 作用 |
|---|---|
| animation-name | 引用的 @keyframes 名称 |
| animation-duration | 单次动画时长 |
| animation-timing-function | 缓动曲线,同 transition |
| animation-delay | 开始前的延迟 |
| animation-iteration-count | 播放次数,infinite 为无限循环 |
| animation-direction | normal / alternate(往返播放)等 |
| animation-fill-mode | 动画前后的状态如何呈现,见下节 |
.badge { animation: pulse 1.6s ease-in-out infinite; }
效果预览:持续脉动
fill-mode 与初始/结束状态
默认情况下,动画播放结束后元素会"跳回"未应用动画时的原始样式;animation-fill-mode 可以让它保留在关键帧定义的状态:
| 取值 | 行为 |
|---|---|
| none(默认) | 动画前后都不应用关键帧样式 |
| forwards | 播放结束后保持最后一帧的样式 |
| backwards | 在 delay 等待期间就提前应用第一帧的样式 |
| both | forwards + backwards 同时生效 |
.enter { animation: fade-up .4s ease-out both; } @keyframes fade-up { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: translateY(0); } }
实战:加载骨架屏
用渐变背景配合 background-position 动画,是"骨架屏加载态"最经典的实现方式:
.skeleton { background: linear-gradient(90deg, #e7e8e1 25%, #f4f5f0 37%, #e7e8e1 63%); background-size: 400% 100%; animation: shimmer 1.4s ease infinite; } @keyframes shimmer { 0% { background-position: 100% 0; } 100% { background-position: 0 0; } }
效果预览