动画

CSS 播客 - 第 022 集:动画

有时,您会在界面上看到一些小助手,点击这些助手后,系统会提供有关该特定部分的实用信息。这些信息通常会显示脉动动画,以巧妙地告知您有信息可用,并且应与之互动。 本单元将介绍如何使用 CSS 创建这些辅助程序和其他动画。

您可以使用 CSS 设置包含关键帧的动画序列。这些序列可以是基本单状态动画,也可以是复杂的基于时间的序列。

什么是关键帧?

在大多数动画工具中,关键帧是您用于将动画状态分配给时间轴上时间戳的机制。

例如,下面是闪烁的“辅助”圆点的时间轴。动画会运行 1 秒,并具有 2 个状态。

1 秒时间范围内的脉冲动画的状态

每种动画状态都有一个特定的开始和结束点。您可以使用关键帧在时间轴上映射这些内容。

与上图相同的示意图,但这次添加了关键帧

@keyframes

Browser Support

  • Chrome: 43.
  • Edge: 12.
  • Firefox: 16.
  • Safari: 9.

Source

CSS @keyframes 基于与动画关键帧相同的概念。

下面是一个包含两个状态的示例:

@keyframes my-animation {
  from {
    transform: translateY(20px);
  }
  to {
    transform: translateY(0px);
  }
}

第一个重要部分是自定义标识符 (custom-ident),即关键帧规则的名称。此示例中的标识符为 my-animation。自定义标识符的运作方式与函数名称类似,可让您在 CSS 代码中的其他位置引用关键帧规则。

在关键帧规则中,fromto 是代表 0%100% 的关键字,分别表示动画的起点和终点。您可以按如下方式重新创建相同的规则:

@keyframes my-animation {
    0% {
        transform: translateY(20px);
    }
    100% {
        transform: translateY(0px);
    }
}

您可以根据需要在相应时间范围内添加任意数量的职位。在脉动辅助功能示例中,有两个状态会转换为两个关键帧。这意味着,您可以在关键帧规则中使用两个位置来表示每个关键帧的变化。

@keyframes pulse {
  0% {
    opacity: 0;
  }
  50% {
    transform: scale(1.4);
    opacity: 0.4;
  }
}

animation 属性

Browser Support

  • Chrome: 43.
  • Edge: 12.
  • Firefox: 16.
  • Safari: 9.

Source

如需在 CSS 规则中使用 @keyframes,您可以单独定义各种动画属性,也可以使用 animation 缩写属性。

animation-duration

Browser Support

  • Chrome: 43.
  • Edge: 12.
  • Firefox: 16.
  • Safari: 9.

Source

.my-element {
    animation-duration: 10s;
}

animation-duration 属性以时间值的形式定义 @keyframes 时间轴的时长。此值默认为 0 秒,这意味着动画仍会运行,但速度太快,您看不到。您不能使用负时间值。

animation-timing-function

Browser Support

  • Chrome: 43.
  • Edge: 12.
  • Firefox: 16.
  • Safari: 9.

Source

为了帮助在动画中重新创建自然的动作,您可以使用用于计算动画在每个时间点的速度的计时函数。计算值通常是曲线,这会使动画在 animation-duration 期间以可变的速度运行,并且如果浏览器计算的值超出 @keyframes 中定义的值,则会使元素看起来像在弹跳。

CSS 中提供了多个可用作预设的关键字,可用作 animation-timing-function 的值:lineareaseease-inease-outease-in-out

.my-element {
    animation-timing-function: ease-in-out;
}

缓动函数值看起来像是曲线,因为缓动是使用 Bézier 曲线计算的,这是一种用于模拟速度的函数。每个时间函数关键字(例如 ease)都引用预定义的贝塞尔曲线。在 CSS 中,您可以直接使用 cubic-bezier() 函数定义贝塞尔曲线,该函数接受四个数值:x1y1x2y2

.my-element {
    animation-timing-function: cubic-bezier(.42, 0, .58, 1);
}

这些值会沿 X 轴和 Y 轴绘制曲线的各个部分。

进度与时间对比图上的贝塞尔曲线

理解贝塞尔曲线很复杂。视觉工具非常有用,例如 Lea Verou 创建的此生成器

steps 缓动函数

有时,您可能希望通过按时间间隔移动(而不是沿曲线移动)来更精细地控制动画。借助 steps() 缓动函数,您可以将时间轴拆分为等时长的定义间隔。

.my-element {
    animation-timing-function: steps(10, end);
}

第一个参数是步数。如果关键帧的数量与步骤相同,则每个关键帧都会按顺序播放其步骤的确切时长,并且状态之间不会有转换。如果关键帧的数量少于步数,浏览器会根据第二个参数在关键帧之间添加步数。

第二个参数是方向。如果将其设置为 end(默认值),则步骤会在时间轴结束时完成。如果将其设置为 start,动画的第一步会在动画开始后立即完成,这意味着动画会比 end 提前一步结束。

animation-iteration-count

Browser Support

  • Chrome: 43.
  • Edge: 12.
  • Firefox: 16.
  • Safari: 9.

Source

.my-element {
    animation-iteration-count: 10;
}

animation-iteration-count 属性用于定义 @keyframes 时间轴在动画期间应运行的次数。默认值为 1,这表示动画会在到达时间轴的末尾时停止。此值不能为负数。

如需让动画循环播放,请将迭代次数设置为 infinite。本课开头的脉动动画就是这样运作的。

animation-direction

Browser Support

  • Chrome: 43.
  • Edge: 12.
  • Firefox: 16.
  • Safari: 9.

Source

.my-element {
    animation-direction: reverse;
}

您可以使用 animation-direction 设置时间轴在关键帧上的运行方向,该属性可采用以下值:

  • normal:默认值,即向前。
  • reverse:向后播放时间轴。
  • alternate:对于每次动画迭代,时间轴会交替向前和向后运行。
  • alternate-reverse:与 alternate 类似,但动画从时间轴向后运行开始。

animation-delay

Browser Support

  • Chrome: 43.
  • Edge: 12.
  • Firefox: 16.
  • Safari: 9.

Source

.my-element {
    animation-delay: 5s;
}

animation-delay 属性用于定义浏览器在开始动画之前等待的时间。与 animation-duration 属性一样,此属性接受时间值。

animation-duration 不同,您可以animation-delay 定义为负值,以便动画从时间轴中的相应时间点开始。例如,如果动画时长为 10 秒,并且您将 animation-delay 设置为 -5s,则动画会从时间轴的中间开始播放。

animation-play-state

Browser Support

  • Chrome: 43.
  • Edge: 12.
  • Firefox: 16.
  • Safari: 9.

Source

.my-element:hover {
    animation-play-state: paused;
}

借助 animation-play-state 属性,您可以播放和暂停动画。默认值为 running。如果将其设置为 paused,动画会暂停。

animation-fill-mode

Browser Support

  • Chrome: 43.
  • Edge: 12.
  • Firefox: 16.
  • Safari: 9.

Source

animation-fill-mode 属性用于定义 @keyframes 时间轴中的哪些值会在动画开始前或结束后保留。默认值为 none,表示动画完成后,时间轴中的值会被舍弃。其他选项包括:

  • forwards:最后一个关键帧会根据动画方向保留。
  • backwards:第一个关键帧会根据动画方向保留。
  • both:第一个和最后一个关键帧都会保留。

animation 简写法

您可以使用 animation 简写形式定义这些属性,而不是单独定义每个属性,这样您就可以按以下顺序定义动画属性:

  1. animation-name
  2. animation-duration
  3. animation-timing-function
  4. animation-delay
  5. animation-iteration-count
  6. animation-direction
  7. animation-fill-mode
  8. animation-play-state
.my-element {
    animation: my-animation 10s ease-in-out 1s infinite forwards forwards running;
}

使用动画时的注意事项

用户可以在与应用和网站互动时将操作系统设置为首选减少动作。您可以使用 prefers-reduced-motion 媒体查询检测此偏好设置:

@media (prefers-reduced-motion) {
  .my-autoplaying-animation {
    animation-play-state: paused;
  }
}

这并不一定表示不显示动画。用户更喜欢减少动画,尤其是减少意外动画。如需详细了解此偏好设置和整体效果,请参阅我们的动画指南

检查您的理解情况

测试您对动画的了解程度

@keyframes 动画的名称或自定义标识符是否区分大小写?

🎉
CSS 不允许 2 个动画具有相同的名称,但允许 SWOOPswoop 共存。

关键字 fromto 与以下内容相同:

startend
再试一次!
0%100%
from0% 相同,to 与 100% 相同。
01
再试一次!

animation-timing-function 也常被称为:

动态时间
再试一次!
延迟
再试一次!
Easing
🎉

@keyframes 动画中所需的关键帧数量下限是多少?

1
浏览器会将元素的当前状态视为关键帧,因此至少需要 1 个关键帧。
2
再试一次!
3
再试一次!
4
再试一次!