您是否曾经想过如何在不使用任何预处理器功能(如 mixin)的情况下自定义 CSS 动画关键帧?我一直为了这个原因而使用预处理器,但能够摆脱另一个依赖关系,使用原生 CSS 真是太好了。
好吧,我找到了一种方法,可以使用纯 CSS 来处理关键帧动画中的变化,这要归功于 自定义属性! 让我们更深入地了解 CSS 关键帧的工作原理,以及如何使用 CSS 和自定义属性来增强它们。
了解 CSS 动画继承
当我们将动画分配给元素时,我们可以自定义其中一些属性,例如持续时间、延迟等。让我向您展示一个虚拟示例:我们有两个类:.walk
和 .run
。 两者都使用相同的动画(名为 breath
),并且 .run
比 .walk
执行得更快(分别为 0.5s
到 2s
)。
@keyframes breath {
from {
transform: scale(0.5);
}
to {
transform: scale(1.5);
}
}
/* Both share the same animation, but walking is _slower_ than running */
.walk {
animation: breath 2s alternate;
}
.run {
animation: breath 0.5s alternate;
}
每次我们重用动画时,**它都会根据我们分配给它的属性而产生不同的行为**。 因此,我们可以说动画会根据应用动画的元素继承其行为。
但动画 *规则* (在本例中为缩放)呢?让我们回到 breath
动画示例:.walk
类以更慢的速度执行 breath
,但也需要更深,因此我们需要更改其缩放值,使其大于 .run
类的缩放值,后者呼吸更浅,更频繁。
在纯 CSS 中,常见的做法是复制原始动画,并在类中直接调整值
@keyframes breath {
/* same as before... */
}
/* similar to breath, but with different scales */
@keyframes breathDeep {
from {
transform: scale(0.3);
}
to {
transform: scale(1.7);
}
}
.walk {
animation: breathDeep 2s alternate;
}
.run {
animation: breath 0.5s alternate;
}
虽然这可以正常工作,但有一个更好的解决方案,它允许我们重用动画的属性和值!怎么做呢?通过利用 CSS 变量继承! 让我们看看如何
/* breath behaves based on the
CSS variables values that are inherited */
@keyframes breath {
from {
transform: scale(var(--scaleStart));
}
to {
transform: scale(var(--scaleEnd));
}
}
.walk {
--scaleStart: 0.3;
--scaleEnd: 1.7;
animation: breath 2s alternate;
}
.run {
--scaleStart: 0.8;
--scaleEnd: 1.2;
animation: breath 0.5s alternate;
}
很酷,对吧?现在,我们不需要编写 *重复* 的动画来从相同的动画中获得不同的效果!
如果您需要更进一步,请记住我们还可以 使用 JavaScript 更新 CSS 自定义属性。 不仅可以更新 根变量,还可以更新特定元素中的变量。 我发现这非常强大,因为我们可以通过利用 JavaScript 来创建更高效的动画,而不会失去 CSS 动画的原生优化。 这真是双赢!
查看 CodePen
使用原生 CSS 的动态 CSS @keyframes,作者为 Sandrina Pereira (@sandrina-p)
在 CodePen 上。
这非常巧妙地利用了自定义属性和作用域。 谢谢。
很棒的技术! 我们是否可以在初始关键帧中设置默认值,如果元素本身具有自定义属性,则会被覆盖?
是的,这正是
var()
函数接受回退值的原因!var(--customProperty, fallbackValue)
。 在这种情况下,类似于transform: scale(var(--scaleStart, 0.5));
。当然,CSS 变量的默认值可以按照以下方式设置
var(–someValue, FALLBACK-VALUE)
哇,上周我确实想过这个问题,因为我试图解决这个问题,而且不想创建各种动画……我对 CSS 变量并不熟悉,它们以前不是我的朋友,现在它们太棒了。 真是太棒了。
好吧,这真的太酷了! 我迫不及待地想用它!