CSS 动画教程:初学者完整指南
已发表: 2022-02-07这是针对初学者的完整语法指南和交互式 CSS 动画教程。 使用它作为参考来学习 CSS 动画规范的不同部分。
在过去的 10 年中,浏览器性能取得了长足的进步。 由于潜在的渲染和性能问题,向网页添加交互式动画过去更具挑战性。 但如今,CSS 动画可以更自由地使用,并且与网格或 flexbox 等 CSS 功能相比,语法通常更容易学习。
W3C CSS 动画规范中有不同的特性。 有些比其他更容易使用。 本 CSS 关键帧动画教程将介绍所有语法,包括每个不同的属性。 我将包含交互式演示,以帮助您掌握 CSS 动画的可能性。
@keyframes 语法
每个 CSS 动画都有两个部分:一个或多个animation-*
属性以及一组使用@keyframes
规则定义的动画关键帧。 让我们详细了解构建@keyframes
规则集的内容。
语法如下所示:
@keyframes moveObject 0% transform: translateX(0); 50% transform: translateX(300px); 100% transform: translateX(300px) scale(1.5);
如此处所示, @keyframes
at-rule 包括三个基本部分:
-
@keyframes
规则后跟自定义动画名称 - 一组包含所有关键帧的花括号
- 一个或多个关键帧,每个关键帧都有一个百分比,后跟一个用花括号括起来的规则集
在我们的 CSS 动画教程的第一个示例中,我使用名称moveObject
定义了我的动画。 这可以是我想要的任何名称,区分大小写,并且必须遵守 CSS 中的自定义标识符规则。 此自定义名称必须与animation-name
属性中使用的名称匹配(稍后讨论)。
在我的示例中,您会注意到我使用百分比来定义动画中的每个关键帧。 如果我的动画包含等于0%
和100%
的关键帧,我可以选择使用from
和to
关键字:
@keyframes moveObject from transform: translateX(0); 50% transform: translateX(300px); to transform: translateX(300px) scale(1.5);
以下交互式 CodePen 在一个实时示例中使用上述语法:
在演示中,我包含了一个重置动画的按钮。 稍后我将解释为什么需要这样做。 但是现在,只要知道这个动画包括三个关键帧,它们代表这个动画序列中的步骤:开始、50% 步骤和结束(即 0%、50% 和 100%)。 其中每一个都使用所谓的关键帧选择器和花括号来定义该步骤的属性。
关于@keyframes
语法的一些注意事项:
- 您可以按您想要的任何顺序放置关键帧规则集,浏览器仍将按照其百分比确定的顺序运行它们
- 您可以省略 0% 和 100% 关键帧,浏览器将根据动画元素的现有样式自动确定这些关键帧
- 如果存在具有不同规则集的重复关键帧(例如,具有不同变换值的 20% 的两个关键帧),浏览器将使用最后一个
- 您可以使用逗号在单个关键帧选择器中定义多个关键帧:
10%, 30% ...
-
!important
关键字使任何属性值无效,因此不应在关键帧规则集中的属性上使用它
现在您已经很好地理解了本 CSS 动画教程中的@keyframes
语法,让我们来看看在动画元素上定义的不同动画属性。
我们将要介绍的动画属性:
动画名称属性
如前所述,您创建的每个 CSS 动画都必须有一个出现在@keyframes
语法中的名称。 此名称必须与使用animation-name
相同。
使用上一个演示中的 CSS,语法如下所示:
.box animation-name: moveObject;
同样,我定义的自定义名称也必须作为@keyframes
at-rule 的名称存在——否则这个名称将不起作用。 你可以把它想象成 JavaScript 中的函数调用。 函数本身是代码的@keyframes moveObject
部分,而函数调用是animation-name: moveObject
。
关于animation-name
一些事情:
-
animation-name
的初始值为none
,这意味着没有关键帧处于活动状态。 这可以用作一种“切换”来停用动画。 - 您选择的名称区分大小写,可以包含字母、数字、下划线和连字符。
- 名称中的第一个字符必须是字母或连字符,但只能是单个连字符。
- 名称不能是保留字,如
unset
、initial
或inherit
。
动画持续时间属性
毫不奇怪, animation-duration
属性定义了动画从开始到结束运行一次所需的时间。 该值可以以秒或毫秒为单位指定,如下所示:
.box animation-duration: 2s;
以上将等同于以下内容:
.box animation-duration: 2000ms;
您可以在下面的 CodePen 演示中看到animation-duration
属性的作用。 在此演示中,您可以选择希望动画持续多长时间。 尝试以秒或毫秒为单位输入各种值,然后使用“Animate the Box”按钮运行动画。
如果您在单位中使用小数字和ms
,您甚至可能不会注意到任何移动。 如果您使用毫秒,请尝试设置更高的数字。
关于使用animation-duration
一些注意事项:
- 负值无效
- 必须包含单位,即使持续时间设置为
0s
(初始值) - 您可以使用小数值(例如
0.8s
)
动画计时功能属性
animation-timing-function
,其含义不如前两个属性明显,用于定义 CSS 动画进行的方式。 这可能不是最清楚的解释,但语法可能有助于澄清。
声明如下所示:
.box animation-timing-function: linear;
此属性接受以下关键字值:
-
ease
(初始值) -
ease-in
-
ease-out
-
ease-in-out
-
linear
-
step-start
-
step-end
大多数值通过它们的名称相对容易掌握,但是您可以通过使用以下交互式演示来了解它们的不同之处:
使用选择输入来选择七个关键字值之一。 请注意, ease-*
以各种方式“缓和”动画。 线性值自始至终都是一致的。
animation-timing-function
属性还接受以下函数:
-
cubic-bezier()
- 接受四个数字值作为参数,用逗号分隔 steps()
– 接受两个值作为参数,一个数字和一个“跳转项”,用逗号分隔
关键字值step-start
和step-end
分别等效于值steps(1, jump-start)
和steps(1, jump-end)
。
至于cubic-bezier()
,下面的交互式演示可能会帮助您更好地理解该函数:
请注意,该演示允许您在cubic-bezier()
函数中设置四个参数。 其中两个参数可以是负数,两个被限制为 0 和 1 之间的十进制值。有关这些类型的计时函数如何工作的正确解释,您可以查看这篇文章或这个交互式工具。
另一方面, steps()
函数接受两个参数:
- 一个整数,表示沿动画的单个循环相等的“停止”。
- 一个称为“jumpterm”的可选关键字,用于确定动画是否以特定间隔“保持”
同样,交互式演示应该可以帮助您掌握这些跳转术语的工作原理:
尝试选择一个整数和一个跳转项(或尝试不使用跳转项)以查看不同的关键字与不同的整数值有何不同。 显然负整数是允许的,但我看不出 0 和任何负值之间有任何区别。
动画迭代计数属性
在某些情况下,如果动画运行一次,您会很高兴,但有时您希望动画运行多次。 animation-iteration-count
属性允许您通过接受一个正数来执行此操作,该正数表示您希望动画运行的次数:

.box animation-iteration-count: 3;
animation-iteration-count
的初始值为1
,但您也可以使用关键字infinite
(不言自明)或使用小数值。 小数值将在小数运行中部分运行动画:
.box animation-iteration-count: 3.5;
上面的代码在动画中运行了三遍半。 也就是说,三个完整的迭代,然后是一个在中途停止的最终迭代。
此属性在与animation-direction
属性(接下来讨论)结合使用时最有用,因为仅从头开始运行的动画如果运行多次则不是非常有用。
您可以尝试下面的演示,它允许您为迭代计数选择一个小数值,这样您就可以看到效果:
动画方向属性
正如上面这个 CSS 动画教程中提到的, animation-direction
属性与animation-iteration-count
配合得很好。 animation-direction
属性允许您定义希望动画播放的方向。 语法如下所示:
.box animation-direction: alternate;
您可以将值设置为以下四个关键字之一:
-
normal
– 动画在第一次迭代时向前播放(默认) -
reverse
– 动画在第一次迭代时向后播放 alternate
- 动画在第一次迭代中向前播放,然后在后续迭代中交替播放alternate-reverse
– 与alternate
相同,但在第一次迭代时向后播放
您可以使用下面的交互式演示尝试具有不同迭代次数的不同值:
动画播放状态属性
animation-play-state
属性在静态 CSS 环境中不是非常有用,但在编写通过 JavaScript 甚至 CSS 交互的动画时可能会派上用场。
此属性接受两个值: running
或paused
:
.box animation-direction: paused;
默认情况下,任何给定的动画都处于“运行”状态。 但是您可以使用 JavaScript 来切换属性的值。 您甚至可以使用交互式 CSS 功能(例如:hover
或:focus
)将动画更改为“暂停”状态,这实际上将动画冻结在当前迭代中的任何位置。
下面的交互式演示有一个无限运行的动画,带有两个按钮来“暂停”和“恢复”动画。
动画延迟属性
一些动画被设计为立即开始动画,而另一些则可以从第一次迭代之前的轻微延迟中受益。 animation-delay
属性允许您完成此操作。
.box animation-delay: 4s;
与其他基于时间的值一样,您可以将animation-delay
设置为使用秒或毫秒的值。 您也可以使用小数值。
重要的是要注意延迟只发生在第一次迭代,而不是每次迭代。 您可以使用下面的交互式演示进行尝试:
该演示为您提供了更改迭代值和延迟的选项,因此您可以看到延迟不会影响任何后续迭代 - 仅影响第一次。
使用此属性的一种有趣方式是使用负值。 例如,使用上面的演示,尝试将animation-delay
设置为-0.5s
。 您会注意到负延迟的工作方式几乎就像在时间机器中前进一样 - 动画从中途开始而不是在开始时开始。
动画填充模式属性
我将在本 CSS 动画教程中介绍的最后一个速记属性是我在上一个演示中使用的属性。 您会注意到,当动画停止最后一次迭代时,框仍保留在原处。 这是使用animation-fill-mode
完成的。
.box animation-fill-mode: forwards;
此属性设置动画在执行之前和之后如何将样式应用于目标元素。 这在概念上有点难以理解,所以我将介绍每个值的含义; 然后您可以使用交互式演示来比较这些值。
此属性接受以下四个关键字值:
-
none
– 默认值,在执行之前或之后不应用样式 forwards
– 保留动画最后一个关键帧中应用的所有样式backwards
- 或多或少与前一个值相反,它在开始执行但在动画开始之前保留应用于动画的样式both
– 保留forwards
和backwards
的样式
这个 CSS 动画教程中的最后一个演示将使事情变得更清晰一些,但是在你真正了解它的作用以及它是如何实现它之前,这个演示可能需要大量的时间。
为方便起见,我已将所有演示添加到单个 CodePen 集合中。
您会注意到该演示允许您调整填充模式、延迟、方向和迭代次数,因为所有这些都会对外观产生影响。 我还在第一个关键帧的动画框中添加了不同的背景颜色,这再次有助于使填充模式值更加清晰。 如果您仍然不太了解animation-fill-mode
工作原理,您可以查看我写的一篇较早的文章,该文章深入讨论了animation-fill-mode
。
动画速记属性
在这个面向初学者的 CSS 动画教程中,我介绍了八种不同的属性,我鼓励你使用长手。 这将使您更容易看到明确的值集。
一旦你对每个属性有了很好的理解,你就可以选择使用animation
速记属性,它允许你在一个声明中定义所有的速记属性。
.box animation: moveObject 2s ease-in-out 3 reverse running 1.3s forwards;
老实说,一行中有很多信息。 如果声明不包括所有属性,但可能只包括其中的三个或四个,我建议使用速记。
如果您确实使用速记,则可以按您想要的任何顺序放置值,但请注意以下规则:
- 定义时间的第一个值是
animation-duration
; 任何后续时间值都是animation-delay
。 - 如果关键字和
animation-name
之间存在冲突,则关键字值将优先出现,如果它首先出现。 - 任何省略的值都将回退到它们的初始状态,就像任何 CSS 速记属性一样。
将多个动画应用于单个元素
最后一个值得注意的功能是,您可以选择通过逗号分隔动画来将多个动画应用于单个对象。
下面是一个使用速记的例子:
.box animation: moveObject 2s ease-in-out, fadeBox 3s linear;
在这里,我定义了两个不同的动画,它们将映射到两组不同的关键帧,但会应用于同一个对象。 同样的代码可以写成:
.box animation-name: moveObject, fadeBox; animation-duation: 2s, 3s; animation-timing-function: ease-in-out, linear;
请注意每个属性如何包含两个用逗号分隔的值。 在这种情况下,速记几乎肯定更容易阅读和维护。
结束这个 CSS 动画教程
如果你是一个 CSS 初学者,并且这个 CSS 动画教程是你第一次尝试在网页上移动东西,我希望这节课足够全面。 您甚至可以将 CSS 变量与动画结合起来,使它们更加强大。
最后一个警告:适度使用动画,并记住一些网络用户可能会受到闪烁颜色和其他快速移动对象的负面影响。
通过练习,构建 CSS 动画的语法和概念会牢牢记住,而且你肯定会从在不同的演示中摆弄代码中受益。