css动画顺序执行应共用容器、统一duration并设forwards,避免animationend事件;可用css变量+calc()动态控制延迟,注意safari兼容性及移动端webview缺陷。

用 animation-delay 控制动画启动时机
多个动画按顺序执行,最直接的方式不是写多个 @keyframes 然后靠 JS 触发,而是让它们共用同一个容器元素,各自定义独立的 animation,再用 animation-delay 错开起始时间。关键点在于:所有动画必须声明相同的持续时间(animation-duration),否则时间轴对不齐。
常见错误是只设 animation-delay 却忽略 animation-fill-mode: forwards,导致前一个动画结束后样式回退,视觉上出现“跳变”。
-
animation-delay值为正数表示等待,负数表示提前播放(慎用,易错) - 若第一个动画时长为
2s,第二个想在它结束后立刻开始,就设animation-delay: 2s - 务必加
animation-fill-mode: forwards,否则动画结束瞬间元素恢复初始状态
把多个动画拆到不同伪元素或子元素上更可控
当动画涉及不同属性(比如一个动 opacity,一个动 transform),强行塞进同一个元素容易互相干扰。此时更适合拆解:用 ::before、::after 或额外的 <span></span> 承载各自动画。
这样每个动画互不抢占渲染层,也避免 transform 和 opacity 同时变化引发的复合层重排问题。
- 父容器设
position: relative,伪元素设position: absolute叠加定位 - 每个子元素单独设
animation和对应的animation-delay - 注意 z-index 层级,避免后启动的动画被先启动的遮住
用 CSS 自定义属性 + calc() 动态算延迟值
当动画序列变长(比如 5 步流程),硬编码 animation-delay: 2s、4s、6s 很难维护。可以改用 CSS 自定义属性统一管理基础时长,再用 calc() 计算各步延迟。
section {
--step-duration: 1.5s;
}
.step-1 { animation-delay: calc(0 * var(--step-duration)); }
.step-2 { animation-delay: calc(1 * var(--step-duration)); }
.step-3 { animation-delay: calc(2 * var(--step-duration)); }
这样改节奏只需调一个 --step-duration,所有延迟自动同步更新。但注意:Safari 对 calc() 在 animation-delay 中的支持直到 iOS 16.4 才稳定,旧版本需降级为静态值。
别依赖 animationend 事件做 CSS 动画串联
有人想用 JS 监听 animationend 再手动触发下一个动画,这在简单场景可行,但实际中极易出问题:浏览器可能因 tab 切换、页面滚动而暂停动画,导致事件不触发;或者动画被强制中断(如 class 移除),事件永远不派发。
CSS 原生的时间轴控制(animation-delay + forwards)更可靠,且无需 JS 干预,渲染性能也更好。
-
animationend事件只在动画自然完成时触发,跳过、取消、中断都不派发 - 移动端 WebView(尤其安卓 X5)对
animationend兼容性差,有漏触发记录 - 真需要 JS 参与逻辑(比如某步失败后重试),应在 CSS 动画结束后用定时器兜底,而非强依赖事件
CSS 动画顺序执行的难点不在“怎么写”,而在“怎么不让它在特定设备或状态下掉帧、跳步、失序”。时间值尽量用秒(s)不用毫秒(ms),避免小数精度误差累积;所有动画的 animation-timing-function 最好统一,否则视觉节奏会断裂。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











