用@keyframes实现多步骤动画只需在一个规则中定义多个百分比节点,如0%→33%→66%→100%,确保transform等属性在每帧完整书写以避免跳变,合理分配时间点并统一单位可保证连贯性。

如何用 @keyframes 实现多步骤连续动画
直接写多个百分比节点就能串起多步骤动画,不需要拆成多个 @keyframes 或靠 JS 拼接。关键在于时间点的精确分配和属性变化的连贯性。
比如从透明到不透明、再平移、最后缩放,三个动作按顺序发生,只需在一个 @keyframes 里定义 0% → 33% → 66% → 100% 四个状态即可。
-
0%:初始状态(opacity: 0; transform: translateX(0) scale(1);) -
33%:完成淡入(opacity: 1;),位置和大小不变 -
66%:完成平移(transform: translateX(100px) scale(1);) -
100%:完成缩放(transform: translateX(100px) scale(0.8);)
注意:transform 必须在每个关键帧中完整写出,浏览器不会自动补全或插值未声明的子属性(比如只写 scale 而漏掉 translateX,会导致该帧回退到 transform: none)。
为什么动画卡在中间或跳变
常见原因是关键帧之间属性类型不一致,或 transform 值未归一化。例如:
立即学习“前端免费学习笔记(深入)”;
- 在
0%写transform: translateX(0),但在50%只写scale(1.2)→ 缺失translateX,浏览器视为transform: scale(1.2),等价于translateX(0) scale(1.2),造成意外重置 - 混用单位:比如
left: 0px和left: 50%同时出现在一个动画中 → 浏览器无法插值,可能跳变或停住 - 未设置
animation-fill-mode: forwards→ 动画结束后元素立刻回到初始状态,看起来像“没执行完”
animation-timing-function 对多步骤的影响
整个动画默认使用同一个缓动函数,但你可以用 animation-timing-function: steps(3, end) 实现逐帧式分步(适合菜单展开、打字效果等),不过它和 @keyframes 百分比动画是两种范式,不能混用。
如果坚持用关键帧做“匀速分段”,更稳妥的方式是手动切分时间比例,并为每段配独立的 ease-in/ease-out:
0% { opacity: 0; }
25% { opacity: 1; } /* 淡入结束 */
25.0001% { transform: translateX(0); } /* 平移起点,避免插值跳跃 */
50% { transform: translateX(100px); } /* 平移结束 */
50.0001% { transform: scale(1); } /* 缩放起点 */
100% { transform: scale(0.8); }这种写法能规避浏览器对同一属性在相邻关键帧间做“智能插值”的副作用,尤其在涉及 transform 组合时很实用。
兼容性和性能提醒
@keyframes 多步骤动画在所有现代浏览器中都支持,但有两点容易被忽略:
- 旧版 Safari(≤ iOS 9.3)不支持
transform中多个函数混写(如translateX(100px) scale(0.8)),需改用matrix()或降级为单属性动画 - 频繁变更
top/left触发重排,而transform和opacity是合成层友好属性,优先选它们 - 如果步骤超过 10 个,建议拆成多个
animation链式调用(用animation-delay控制时机),否则关键帧列表过长会增加 CSS 解析开销,且难以维护
真正难的不是写多少个百分比,而是想清楚哪几个状态必须显式声明、哪些可以交给浏览器插值——这决定了动画是否顺滑、是否跨设备一致。










