使用自定义属性处理关键帧动画的变化

Avatar of Sandrina Pereira
Sandrina Pereira

DigitalOcean 提供适用于您旅程每个阶段的云产品。 立即开始使用 $200 免费积分!

您是否曾经想过如何在不使用任何预处理器功能(如 mixin)的情况下自定义 CSS 动画关键帧?我一直为了这个原因而使用预处理器,但能够摆脱另一个依赖关系,使用原生 CSS 真是太好了。

好吧,我找到了一种方法,可以使用纯 CSS 来处理关键帧动画中的变化,这要归功于 自定义属性! 让我们更深入地了解 CSS 关键帧的工作原理,以及如何使用 CSS 和自定义属性来增强它们。

了解 CSS 动画继承

当我们将动画分配给元素时,我们可以自定义其中一些属性,例如持续时间、延迟等。让我向您展示一个虚拟示例:我们有两个类:.walk.run。 两者都使用相同的动画(名为 breath),并且 .run.walk 执行得更快(分别为 0.5s2s)。

@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 上。