纯css可实现阶梯式逐项入场动画,需用@keyframes+animation而非transition;scss的@for简化延迟计算,但动态列表需js或css变量配合;起始状态须设transform: translatey(20px) opacity: 0并配合overflow: hidden确保阶梯感。

纯 CSS 就能实现阶梯式逐项入场动画,SCSS 只是用来简化延迟计算的可选工具——不依赖预处理器也能做,但用 $i 和 @for 确实省去手写十几次 animation-delay 的麻烦。
为什么用 animation-delay 而不用 transition-delay
transition-delay 只在状态变化(比如 hover、class 切换)时触发一次,而阶梯动画需要每个列表项在页面加载后按顺序自动播放。必须用 @keyframes + animation 才能控制循环、方向和独立延迟。常见错误是把 transition 当成入场动画主力,结果只有第一次切换有效,后续刷新或重渲染就失效。
-
animation是声明式、自驱动的,适合初始化动效 -
transition是响应式、事件驱动的,适合交互反馈 - 若混用,
animation-fill-mode: forwards和transition的最终态可能冲突,导致跳帧或错位
SCSS 中用 @for 自动生成延迟值
手动写 .item:nth-child(1) { animation-delay: 0.1s; } 到 nth-child(10) 容易漏、难维护。SCSS 的 @for 可以把逻辑收口:
@for $i from 1 through 10 {
.item:nth-child(#{$i}) {
animation-delay: #{$i * 0.1}s;
}
}
注意点:
-
#{$i * 0.1}必须带单位s,否则编译报错 - 如果列表项数量动态变化(比如由 JS 渲染),SCSS 预编译就无能为力,得改用 CSS 自定义属性 +
:nth-child()计算,或 JS 控制 - 延迟总时长别超过动画本身持续时间,否则末尾几项几乎没动画感;建议单次动画时长 ≥ 总延迟时长 × 0.8
animation-timing-function 对阶梯感的影响
用 ease-in 或 cubic-bezier(0.2, 0.8, 0.4, 1) 比 linear 更显“逐级跃升”——因为每项都是从静止加速启动,视觉上更像踩上一级新台阶。反例是全用 ease-out:所有项都慢悠悠收尾,阶梯变成“软塌塌的坡道”。
- 推荐组合:
animation: fadeUp 0.4s ease-in forwards - 避免在
@keyframes里再设timing-function,它会被元素上的animation-timing-function覆盖 - 移动端要注意
ease-in在低端安卓 WebView 中偶有卡顿,可降级为ease
真正容易被忽略的是容器的 overflow: hidden 和列表项的 transform: translateY() 起始位置配合——如果所有项初始都堆在视口内,即使加了延迟,第一项动画还没结束,第二项就已部分可见,阶梯感就被“糊”掉了。必须让它们起始时统一 transform: translateY(20px) opacity: 0,再靠动画拉回,才能干净利落。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











