动画元素,在最基本的情况下,相当简单。 定义关键帧。 命名动画。 在元素上调用它。
但有时我们需要更复杂的东西才能获得事物移动方式的正确“感觉”。 例如,均衡器可能会在每个条形上使用相同的动画,但它们是交错的,给人以独立动画的错觉。
查看 Pen
Apple Music 音频均衡器在 SVG 中 由 Geoff Graham (@geoffgraham)
在 CodePen 上。
我最近正在构建一个仪表板,并且希望其中一个窗口小部件中的项目以交错动画的方式流入视图。
就像上面的均衡器一样,我开始使用 :nth-child
路线。 我使用无序列表 (<ul>
) 作为父容器,为它提供一个类并使用 :nth-child
伪选择器通过 animaton-delay
来偏移每个列表项。
.my-list li {
animation: my-animation 300ms ease-out;
}
.my-list li:nth-child(1) {
animation-delay: 100ms;
}
.my-list li:nth-child(2) {
animation-delay: 200ms;
}
.my-list li:nth-child(3) {
animation-delay: 300ms;
}
/* and so on */
这种技术确实可以很好地交错项目,特别是在您知道列表中将有多少项目的情况下。 但是,当项目数量不可预测时,事情就会崩溃,这正是我为仪表板构建的小部件的情况。 我真的不想每次列表中的项目数量发生变化时都回到这段代码,所以我敲出了一个快速 Sass 循环,它可以处理最多 50 个项目并为每个项目递增动画延迟。
.my-list {
li {
animation: my-animation 300ms ease-out;
@for $i from 1 through 50 {
&:nth-child(#{$i}) {
animation-delay: 100ms * $i;
}
}
}
}
应该可以了! 但是,感觉太 hacky 了。 当然,它不会给文件增加太多重量,但您知道编译后的 CSS 将包含很多未使用的选择器,例如 nth-child(45)
。
一定有更好的方法。 通常情况下,我会使用 JavaScript 来查找所有项目并添加延迟,但是……这次我花了一些时间探索,看看是否有一种方法可以使用 CSS 来完成。
CSS 计数器怎么样?
我想到的第一件事是将 CSS 计数器与 calc()
函数结合使用。
.my-list {
counter-reset: my-counter;
}
.my-list li {
counter-increment: my-counter;
animation-delay: calc(counter(my-counter) * 100ms);
}
不幸的是,这行不通,因为规范说 计数器不能在 calc()
中使用)。
calc()
表达式的组成部分可以是文字值或attr()
或calc()
表达式。
事实证明,有些人喜欢这个想法,但它还没有超出 草案阶段。
数据属性怎么样?
在阅读了规范中的那段摘录后,我了解到 calc()
可以使用 attr()
。 而且,根据 CSS 值和单位规范)。
在 CSS3 中,
attr()
表达式可以返回多种不同类型
这让我想到;也许数据属性可以做到这一点。
<ul class="my-list">
<li data-count="1"></li>
<li data-count="2"></li>
<li data-count="3"></li>
<li data-count="4"></li>
</ul>
.my-list li {
animation-delay: calc(attr(data-count) * 150ms);
}
但我的希望破灭了,因为对它的浏览器支持实在太糟糕了!
此浏览器支持数据来自 Caniuse,它提供了更多详细信息。 数字表示浏览器从该版本开始支持该功能。
桌面
Chrome | Firefox | IE | Edge | Safari |
---|---|---|---|---|
否 | 否 | 否 | 否 | 否 |
移动设备 / 平板电脑
Android Chrome | Android Firefox | Android | iOS Safari |
---|---|---|---|
否 | 否 | 否 | 否 |
所以,回到起点。
自定义属性怎么样?
我想到的下一个想法是使用 CSS 自定义属性。 它并不漂亮,但它确实有效 🙂
查看 Pen
CSS 变量动画顺序 由 Dan Benmore (@dbenmore)
在 CodePen 上。
事实证明它非常灵活。 例如,动画可以反转。
查看 Pen
CSS 变量反转动画顺序 由 Dan Benmore (@dbenmore)
在 CodePen 上。
它还可以做一些完全随机的事情,并同时动画化元素。
查看 Pen
CSS 变量随机动画顺序 由 Dan Benmore (@dbenmore)
在 CodePen 上。
我们甚至可以更进一步,做一个对角线挥动。
查看 Pen
使用 CSS 属性/变量设置动画交错 由 Dan Benmore (@dbenmore)
在 CodePen 上。
浏览器支持并不差(戳戳 Internet Explorer)。
此浏览器支持数据来自 Caniuse,它提供了更多详细信息。 数字表示浏览器从该版本开始支持该功能。
桌面
Chrome | Firefox | IE | Edge | Safari |
---|---|---|---|---|
49 | 31 | 否 | 16 | 10 |
移动设备 / 平板电脑
Android Chrome | Android Firefox | Android | iOS Safari |
---|---|---|---|
127 | 127 | 127 | 10.0-10.2 |
CSS 的一大优点是它 会忽略它不理解的东西,这得益于 层叠。 这意味着所有内容都将一起动画化进入视图。 如果您不喜欢,可以添加一个功能查询来覆盖默认动画。
.my-list li {
animation: fallback-animation;
}
@supports (--variables) {
.my-list li {
animation: fancy-animation;
animation-delay: calc(var(--animation-order) * 100ms);
}
}
纯 CSS FTW
我越停下来问自己是否需要 JavaScript,就越惊讶于 CSS 本身能做些什么。 当然,如果 CSS 计数器可以在 calc()
函数中使用,那将是一个非常优雅的解决方案。 但目前,内联自定义属性提供了一种强大且灵活的方式来解决这个问题。
如果您使用某种模板语言,一种简单的方法是在 style 属性上内联一个 transition-delay 属性,如下所示
{% for i in 0..10 %}
{% endfor %}
我仍然会选择在循环中设置索引变量,而不是设置
transition-delay
或其他类似属性。 这是因为索引变量对于设置多个属性很有用。 例如,此索引也可以控制background
的色调或水平偏移。它还可以控制
transition-duration
,如果我们希望它有所不同,或者控制多个持续时间和延迟,如果我们希望为多个属性设置动画。上周我刚刚将它应用于一个网站,使用的是 Sass 循环。 现在我要尝试自定义属性方法。 感谢您撰写这篇文章!
不错! 我在 SASS/SCSS 中比在 styled-components 中更喜欢交错延迟。 将这个想法与 React 中的映射索引结合起来将使这变得非常容易。 你真是太棒了!
反正我都是用 React 构建所有东西,所以我只使用索引来添加动画延迟乘数。 您的方法仍然要求您为每个元素编写一个变量,这在动态列表中不起作用。
Sass 循环真是个好主意。 我没有希望在没有 js 的情况下做这些事情。 非常感谢。 我以后会更加关注 css。
我只是使用 JS 路线
好文章。 交错动画,尤其是延迟动画的一个问题是,广告较多的页面,主线程繁忙,经常会破坏这种效果(IOS 更糟)。
您可能仍然需要仅在线程空闲时才进行动画。
好文章,好想法