CSS 动画技巧:状态跳转、负延迟、动画原点,以及更多

Avatar of Zach Saucier
Zach Saucier

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

我养成了在闲暇时间创建 CSS 动画的习惯,灵感来自我在白天遇到的各种事物。为了用尽可能少的元素创建我设想的动画,我发现了一些技巧,让 CSS 做一些你可能不知道它能做的事情。 我想与大家分享这些技巧。

#1) 动画过程中跳转到另一个状态

CSS 动画让属性随着时间推移过渡到新值变得容易。 它们还有能力在几乎瞬间跳转属性到一个新值。 诀窍是使用两个关键帧,它们之间的差异非常小,大约 .001% 就很有效。

@keyframes toggleOpacity {
  50% { opacity: 1; } /* Turn off */
  50.001% { opacity: 0.4; }

  /* Keep off state for a short period */

  52.999% { opacity: 0.4; } /* Turn back on */
  53% { opacity: 1; }
}

下面是一个极端的例子,它切换不透明度和文本阴影来模拟闪烁的广告牌灯光。

查看 CodePen 上 Zach Saucier (@Zeaklous) 的 No Vacancy 404 纯 CSS

#2) 负动画延迟

正动画延迟是指动画等待一段时间才能开始。 动画延迟是指动画立即开始,就好像已经过去了这段时间一样。 换句话说,在动画循环中更后面的状态开始动画。 这使得动画可以在多个元素中重复使用,因为唯一需要改变的是时间。

这是一个例子,每个圆圈在动画循环中不同的状态立即开始。

查看 CodePen 上 Zach Saucier (@Zeaklous) 的 圆圈蛇

#3) 比例动画

我尽量让所有投入生产的东西都尽可能地响应式,包括我的动画。 我创建的所有动画都不可能都实现响应式,但有时可以,使用百分比和其他相对单位。

在我的许多动画中,我使用圆形和正方形之类的元素,它们需要比例宽度和高度。 你可能认为我需要使用固定宽度和高度值来保持这种比例,但事实并非如此! 我可以使用百分比宽度、零高度和百分比填充来创建它们。 底部填充是保持它与宽度成比例的诀窍,就像这样

.container {
  position: relative;
  display: block;
  width: 100%;
  height: 0;
  padding-bottom: 100%;
}

你可以在下面的演示中看到它的实际效果,通过改变它所在的窗口大小。 演示还使用了负动画延迟。

查看 CodePen 上 Zach Saucier (@Zeaklous) 的 响应式 CSS 条形

#4) 动画过程中更改 transform-origin

在制作我的一个动画时,我惊讶地发现,不仅可以 变换原点 在动画过程中改变,它也可以进行动画! 在下面的例子中,这使我们能够使用不同轴上的旋转来创建一个动画,而不是使用四个单独的动画。

查看 CodePen 上 Zach Saucier (@Zeaklous) 的 在动画过程中更改变换原点

这个技巧的缺点是,你无法将 animation-mode: forwards; 应用到动画的一部分。 这意味着我们必须将元素重新定位到等效于其状态的位置,然后再应用 变换原点 的更改。 在上面的例子中,这是通过使用平移来模拟旋转的效果来实现的。 然而,这种技术在更复杂的例子中可能会变得很繁琐,就像这里所看到的

#5) 负变换原点

你可以设置一个负的 transform-origin,这对创建圆形运动路径很有用。 相比于使用一个元素来创建圆形动画,像 Lea Verou 所描述的那样,通过指定特定的平移和旋转值,我们只需使用负 transform-origin 值以及第二个元素或伪元素(如果我们希望元素旋转并沿圆形路径移动,则为一个元素)就可以更简单地实现。 通过使用不同的负变换原点值,我们可以对多个元素重复使用相同的动画,同时仍然保持每个元素的圆形运动。

查看 CodePen 上 Zach Saucier (@Zeaklous) 的 CSS 圆形运动技术

#6) 盒阴影魔法

对于简单的无内容形状的动画,盒阴影 非常有用。 盒阴影属性可以 在元素周围创建多个边框。 结合一些位移,这个想法可以从没有额外的 HTML 元素中创建新的可动画的“元素”。 这使我们能够创建以下动画,它看起来像是六个圆形元素在圆周上旋转,但实际上是一个元素,带有一些偏移的盒阴影形状。

查看 CodePen 上 Zach Saucier (@Zeaklous) 的 单元素颜色加载器

遗憾的是,百分比不受任何盒阴影属性的支持,因此它们不像原生 HTML 元素那样容易实现响应式。 然而,它们仍然可以在动画中手动更改,或者通过对它们所属的实际 HTML 元素使用 transform:scale(n) 来更改。

#7) 使用伪元素

与盒阴影类似,伪元素可以用来为单个元素的外观添加更多内容。 它们可以与它们的父元素拥有独立的动画、自己的盒阴影,并且与 HTML 标记中的子元素非常相似。 这使我们能够创建像下面这样的惊人的单元素创作。

查看 CodePen 上 Zach Saucier (@Zeaklous) 的 单元素 GIF 复制

在例子中,中间闪烁的圆圈周围的所有大圆圈,以及边缘上的两个小圆圈(彼此相对),都是主元素的盒阴影。 另外两个小圆圈是伪元素的盒阴影的一部分,由短划线组成的圆环是一个作为另一个伪元素的背景应用的 SVG。

其他一些需要注意的事项

尽可能使用变换

变换比非变换的对应方法性能更好,正如 Paul Irish 所示此外)。 主要意味着使用缩放和平移,而不是改变尺寸或顶部/左边的值。

变换也能实现更具响应性的设计,例如使用 `scale` 相对于原始大小进行缩放,正如 Amos 的这个动画 所示。

不使用变换可能会导致难以发现的问题。例如,在我的 这个动画 中,元素在 Chrome 中的颜色显示不正确,尽管值本身是正确的。在 切换到使用变换 后,我的所有问题都解决了。

z-index 可能导致问题

我可能在修复动画的 `z-index` 问题上花费的时间比其他任何问题都多。各个供应商对 z-index 的处理方式不同。在动画中,主要区别在于 Mozilla 不对 z-index 值进行动画处理,而是让元素从一个 z-index 跳到另一个 z-index,而 Webkit 等供应商则对 z-index 值进行动画处理。

需要注意的是,如果希望伪元素显示在父元素后面,则伪元素必须具有负 z-index,而父元素不能有除默认值以外的堆叠,这意味着不能应用 z-index 或任何其他将父元素从其自然堆叠上下文移除的东西。

关于 z-index 的最后一个技巧是与透明度相关的。当元素被赋予除默认值 "1" 以外的透明度时,它会获得自己的堆叠上下文。有关更多信息,请查看 Philip Walton 的文章

获得灵感

无论是现实世界中看到的、在线上找到的有趣的网页、视频介绍的一部分、gif 还是其他任何东西,找到你认为有可能创建的东西,然后尝试去创造!

我发现不看原始作者是如何创建的可以让我学习,以独特的风格进行创造,有时甚至以更高效的方式进行。即使最终没有达到最初的意图,我也总会对所使用的语言更加熟悉或了解更多。很多时候我会有东西可以展示,即使它没有达到我的最初期望那么宏伟。有时我会对自己的作品的出色程度感到完全惊讶,因为我根本没有想过要让它变得如此出色!

我希望这篇文章能帮助你构建更出色的作品,即使你没有从具体的技巧中学到任何东西!