sass 的 @for 循环可批量生成不同 animation-delay 值,如 @for $i from 1 through 5 { li:nth-of-type(#{$i}) { animation-delay: #{($i - 1) * 0.1}s; } },需注意索引偏移、插值语法、nth-of-type 更稳妥、抽离 @keyframes、添加 forwards 保持终态、变量控制项数及单位统一。

用 @for 生成不同 animation-delay 值
核心思路是:CSS 动画本身不支持“自动按序延迟”,必须手动为每个列表项设置不同的 animation-delay。Sass 的 @for 可以帮你批量生成这些值,避免手写 10 行重复代码。
假设你有 5 个列表项,想让它们从上到下依次延迟 0.1s 触发动画,直接写:
@for $i from 1 through 5 {
li:nth-child(#{$i}) {
animation-delay: #{($i - 1) * 0.1}s;
}
}
注意两点:$i - 1 是为了让第一个元素延迟 0s(不是 0.1s),#{...} 是插值语法,不能漏掉大括号。
配合 nth-child 时别混淆索引起点
常见错误是把 @for $i from 1 through 5 和 li:nth-child(#{$i}) 搭配后,发现第 1 个 li 没生效——大概率是因为 HTML 中 li 前面混入了其他兄弟元素(比如注释、空格文本节点,或意外的 div),导致 :nth-child(1) 匹配的不是第一个 li,而是它前面那个元素。
- 更稳妥的方式是用
li:nth-of-type(#{$i}),它只计算同类型(li)元素的顺序 - 或者确保 HTML 结构干净:
ul下直接是连续的li,中间无其他标签或文本 - 调试时可在浏览器里检查元素实际的
:nth-child(n)值,右键“检查”看 computed 样式里的animation-delay是否如预期
动画性能关键:别在 @for 里重复定义整个动画规则
有人会把整个 @keyframes 或整套动画属性塞进循环里,比如:
@for $i from 1 through 3 {
li:nth-of-type(#{$i}) {
animation: slideIn 0.3s ease-out #{($i - 1) * 0.1}s;
}
}
这本身没问题,但如果你后续要改动画时长或缓动函数,就得改多处。更好的做法是抽离动画声明:
@keyframes slideIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
<p>@for $i from 1 through 3 {
li:nth-of-type(#{$i}) {
animation: slideIn 0.3s ease-out #{($i - 1) * 0.1}s forwards;
}
}</p>
forwards 很重要——它让动画停在最后一帧,否则元素可能闪回初始状态。
动态项数?用 Sass 变量控制循环上限
如果列表项数量不固定(比如 CMS 输出),硬编码 through 5 就不灵活。可以定义变量:
$list-count: 7;
<p>@for $i from 1 through $list-count {
li:nth-of-type(#{$i}) {
animation-delay: #{($i - 1) * 0.12}s;
}
}</p>
但要注意:Sass 编译时变量值必须是已知常量,不能是 JS 运行时才确定的数量。也就是说,这个方法适合构建时就确定项数的场景(如静态页面、Jekyll/Hugo 等)。如果是 React/Vue 动态渲染,得换 JS 控制延迟,Sass 此时只负责提供基础动画样式。
真正容易被忽略的是单位一致性:0.1s 和 100ms 混用会导致计算出错;还有 @for 不支持小数步进(比如 from 1 to 5 by 0.5 会报错),必须用整数索引再换算成时间。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











