用 @keyframes 避免重复的核心是定义通用关键帧(如 fadeInUp)并复用,通过 animation-delay 错开节奏;善用 cubic-bezier() 控制质感,必加 animation-fill-mode: forwards 保持终态,将动画视为状态转换而非属性快照。

用 @keyframes 做 HTML5 动画,核心不是堆属性,而是拆解运动逻辑、复用关键帧、控制时序节奏——否则代码越写越多,一改全崩。
怎么用 @keyframes 避免重复写相同动画片段
多个元素做同类型位移(比如都从左进、淡入、缩放),别每个都写一遍 @keyframes slideIn。统一定义一个可参数化的行为,再用 animation 的 delay 和 duration 错开节奏:
- 定义一个通用
@keyframes fadeInUp,只包含opacity、transform: translateY()和scale() - 对不同元素分别设
animation: fadeInUp 0.6s ease-out 0.2s forwards,靠animation-delay实现逐个入场 - 避免为“第2个元素慢0.1s”单独复制一份 keyframes —— 这是维护灾难的起点
animation-timing-function 不只是 ease 和 linear
真实动效靠缓动曲线区分质感。CSS 提供了 cubic-bezier() 和预设值,但很多人只停留在 ease-in-out:
-
animation-timing-function: cubic-bezier(0.34, 1.56, 0.64, 1)可模拟有弹性的回弹效果(注意 y 值可 >1) -
step-start和step-end适合做帧动画式切换(如菜单展开、打字机文字),完全跳过过渡 - 多个动画叠加时,timing-function 不一致会导致视觉脱节——比如旋转用
linear,位移用ease,看起来就像部件没装牢
为什么 animation-fill-mode: forwards 经常被漏掉
动画播完默认回到初始状态,这在交互中极容易引发 UI 跳变。比如一个侧边栏 slideIn 后,鼠标移开就突然消失:
立即学习“前端免费学习笔记(深入)”;
- 必须加
animation-fill-mode: forwards,让最后一帧样式保留 - 若同时用了
transform和opacity,forwards会同时维持两者,不用额外写transform: translateX(0); opacity: 1; - 注意:
forwards不会覆盖 CSS 中显式声明的值(比如你写了opacity: 0.5在元素上,动画里设opacity: 1并加forwards,最终还是 1)
真正省代码的关键,是把动画当状态转换来设计,而不是时间轴上的属性快照。一个 @keyframes 能复用几次,取决于你有没有提前想清楚「哪些变化是耦合的」「哪些节奏是可以错开的」——而不是等加到第5个元素时,才发现 keyframes 已经复制粘贴了三遍。











