用 animation-delay 配合 :nth-child 实现阶梯延迟,需为每个子元素显式设置递增的延迟值(如 0s、0.2s、0.4s),:nth-child 按 dom 顺序精确匹配,不可用 :nth-of-type 替代;禁用 transition-delay,必须配合 @keyframes 使用;推荐 transform/opacity 提升性能,并用 css 变量 + calc() 简化动态管理。

用 animation-delay 配合 :nth-child 控制阶梯延迟
阶梯式延迟的本质,就是让每个子元素的动画起始时间错开。最直接的方式是给每个子元素单独设置 animation-delay,但手动写 10 个不同值太蠢。用 :nth-child(n) 选择器批量处理更可靠。
常见错误是写成 :nth-of-type——它只认标签类型(比如所有 div),而阶梯延迟通常依赖 DOM 顺序,哪怕中间夹着 span 或注释节点,:nth-child 才真正按“第几个子节点”计数。
- 假设父容器是
.steps,子项是.step,则.steps .step:nth-child(1) { animation-delay: 0s; } .steps .step:nth-child(2) { animation-delay: 0.2s; }-
.steps .step:nth-child(3) { animation-delay: 0.4s; }—— 每次递增固定步长,形成线性阶梯
避免用 transition-delay 替代 animation-delay
很多人想省事,把动画逻辑全塞进 transition,再靠 transition-delay 实现延迟。这行不通:transition 只在属性“变化瞬间”触发一次,无法循环或维持状态;而阶梯式效果往往需要反复播放(比如 loading 动画),必须用 @keyframes + animation。
另一个坑是误以为给父元素加 transition-delay 能影响子元素——不会。transition 和 animation 的延迟作用域严格限定在声明它的那个元素上,不继承、不传播。
- ✅ 正确:每个
.step自己声明animation: bounce 0.6s ease-in-out infinite;和animation-delay: calc((n - 1) * 0.15s); - ❌ 错误:只在父元素设
transition-delay: 0.3s,指望子元素跟着延后入场
用 CSS 变量简化重复计算
硬写一堆 :nth-child(n) 规则维护成本高,尤其当子元素数量动态变化时。CSS 自定义属性(变量)配合 calc() 是更可持续的方案。
关键点在于:CSS 变量可以被后代继承,但 calc() 中的表达式必须在使用处求值,不能在变量定义里写公式。所以得在每个子元素上设变量,再统一用。
- 给每个
.step加内联样式:style="--delay: calc((var(--index) - 1) * 0.18s);"(需 JS 注入--index) - 或纯 CSS 方案:
.step:nth-child(1) { --delay: 0s; },.step:nth-child(2) { --delay: 0.18s; }……然后统一写animation-delay: var(--delay); - 注意:Safari 旧版本对
calc()在animation-delay中的支持不稳定,建议用具体数值兜底
性能敏感场景必须用 transform + opacity
如果阶梯动画涉及位置移动(比如从下往上逐个弹出),千万别用 top / left 或 margin。这些属性会强制浏览器每帧都做 Layout 和 Paint,低端 Android 机上极易掉帧。
正确做法是只动 transform: translateY() 和 opacity。它们走的是合成线程(Composite),跳过 Layout/Paint,60fps 更稳。
- ❌ 危险写法:
animation: slideUp 0.4s; @keyframes slideUp { to { top: 0; } } - ✅ 安全写法:
animation: slideUp 0.4s; @keyframes slideUp { to { transform: translateY(0); opacity: 1; } } - 额外提醒:若子元素本身有
position: absolute,确保其父容器有transform: translateZ(0)或will-change: transform,否则部分浏览器可能不启用硬件加速
实际中最容易被忽略的是动画重绘边界——当阶梯项数量多、DOM 深度大时,哪怕用了 transform,如果父容器没有明确的 contain: layout paint,浏览器仍可能扩大重绘区域。这个细节在小项目里不显眼,一到中后台系统列表页就暴露卡顿。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











