如何通过CSS计数器实现基于元素数量的动画延迟?
你的思路真的很有意思,但可惜目前CSS的animation-delay属性没办法直接用counter()函数做算术运算——counter(items)返回的是计数器的字符串形式,没法直接参与数值计算生成时间值,所以你写的这段代码不会生效。
不过有几种纯CSS的解决方案可以实现你想要的效果,根据你的场景选就行:
方案1:利用CSS Grid自动生成延迟(最简洁,适配任意数量)
这个方案不需要手动设置索引,通过Grid布局的行号自动计算延迟,完美适配未知数量的列表项:
@keyframes myAnimation { 0% { opacity: 0; transform: translateX(-20px); } 100% { opacity: 1; transform: translateX(0); } } ul { display: grid; /* 让每个li自动占一行,行号会自动递增 */ list-style: none; padding: 0; } li { animation: myAnimation 0.6s forwards; /* 第一个li行号是1,延迟0s;第二个行号2,延迟0.2s,以此类推 */ animation-delay: calc((grid-row-start - 1) * 0.2s); }
注:
grid-row-start是Grid布局中元素的起始行号,默认会从1开始自动递增,完美契合我们的索引需求。
方案2:相邻兄弟选择器递加索引变量(无需修改布局)
如果不想改变列表的布局,可以用相邻兄弟选择器来递增自定义变量,实现延迟的递进:
@keyframes myAnimation { 0% { opacity: 0; transform: translateX(-20px); } 100% { opacity: 1; transform: translateX(0); } } ul { list-style: none; padding: 0; } /* 第一个li的索引为0,延迟0s */ li { --item-index: 0; animation: myAnimation 0.6s forwards; animation-delay: calc(var(--item-index) * 0.2s); } /* 每个后续的li,索引在前一个基础上加1 */ li + li { --item-index: calc(var(--item-index) + 1); }
这个方案在现代浏览器(Chrome 65+、Firefox 60+、Safari 12.1+)都能正常工作,不需要依赖任何预处理器。
方案3:预处理器循环(适合固定/可预定义数量的场景)
如果你用Sass、LESS这类预处理器,可以自动生成对应数量的样式,不用手动写每个nth-child:
@keyframes myAnimation { 0% { opacity: 0; transform: translateX(-20px); } 100% { opacity: 1; transform: translateX(0); } } ul { list-style: none; padding: 0; } li { animation: myAnimation 0.6s forwards; } // 生成1到20个li的延迟样式,可按需调整数量 @for $i from 1 through 20 { li:nth-child(#{$i}) { animation-delay: calc((#{$i} - 1) * 0.2s); } }
以上几种方案都能实现你要的“根据元素数量设置动画延迟”的效果,推荐优先试试方案1或2,纯CSS就能搞定~
内容的提问来源于stack exchange,提问作者Pablo Christiano
相关产品推荐
相关产品推荐

