我相信很多前端开发人员都有基于CSS @keyframes
创建动画的经历。甚至其中有很多人创建了一些很复杂的动效和去实验这个特性。
如果你想要全面了解这篇文章将要介绍的内容,建议你花点时间阅读我2011年在Smashing Magazine介绍的一个主题,这篇文章也是非常不错的。不过,在今天这篇文章中,我并不想介绍有关于CSS动画中所有的属性,我只想专注于CSS动画中的一个属性:animation-fill-mode
属性。
这个动画属性对动画影响并不很明显。例如没有人会对CSS动画中animation-name
、animation-duration
等属性感到困惑。但对于animation-fill-mode
呢?我们接下来通过一些简单的示例来阐述。
animation-fill-mode语法
你可能知道,一个基于关键帧的动画,它是使用@keyframes
来定义的。但关键帧它自身并不会做任何事,除非你把关键帧声明好的动画名与元素结合在一下。在CSS中可以通过animation
这个属性来完成,你可能明白我的意思:
.example {
animation: myAnim 2s 500ms 2 normal ease-in forwards;
}
当然,上面简写的属性,其扩展出来如下所示:
.example {
animation-name: myAnim;
animation-duration: 2s;
animation-delay: 500ms;
animation-iteration-count: 2;
animation-direction: normal;
animation-timing-function: ease-in;
animation-fill-mode: forwards;
}
在上面的两个示例中animation-fill-mode
的属性值都是forwards
。
再次,即使你从来不使用CSS动画,你也可以轻易的明白上面的声明是什么意思——除了animation-fill-mode
属性之外。
animation-fill-mode的规范
在W3C规范中是这样描述这个属性:
The
animation-fill-mode
property defines what values are applied by the animation outside the time it is executing.
继续解释,外面("outside")的执行。具体的说,它能够控制元素在动画执行前与动画完成后时间。言外之意,animation-fill-mode
的值能够它能够控制元素在动画执行前与动画完成后样式。听起来令人非常困惑,但你会明白我的意思。
animation-fill-mode
它能够控制元素在动画执行前与动画完成后的样式。一个带有延迟(animation-delay
),并且按正常方向(animation-direction
)执行的动画(正常方向是指normal
也就是指动画从0%
运行到100%
的动画)。动画按执行时间来划分,它分为三个过程,或者说一次动画过程可以将元素划分为三个状态:动画等待、动画进行和动画结束。默认情况之下,只有在动画进行状态,才会应用@keyframes
所声明的动画;而在动画等待和动画结束状态,对元素样式并不会产生任何的影响。
接下来观察它的每一个值产生的效果,进一步了解其每个值的定义,当然理解起来可能还会令人有些困惑。
解释animation-fill-mode的每个值
animation-fill-mode
属性可以接受none
、forwards
、backwards
或者both
四个值中的一个值。接下来分别来解释每个值对其影响。
none
none
是animation-fill-mode
的初始值,也是其默认值。如果首先设置了none
,但想改变其值的话,你需要通过JavaScript来完成或者是通过样式来覆盖。正是这个值,使用得动画不会对动画等待和动画完成的元素样式产生改变。
如果不理解这个值,并不重要,我们可以通过一个示例来加强理解。下面的示例是animation-fill-mode:none;
的效果:
下图是录制的动画时间轴效果:
你可以看到,在大多数情况下,animation-fill-mode
取值为none
并不是你想要的东西。记住,取值为none
时,使用得动画不会对动画等待和动画完成的元素样式产生改变。
在这个示例中,开始是一个红色球,然后逐渐变成粉红色,同时向右移动和改变其大小。如果动画结束时,球停止在变小、粉红色、居于右侧,这样效果会更好。这将避免动画一完成就会立马跳回到一开始的位置,避免丑陋的动画效果出现。
forwards
接下来的示例,把animation-fill-mode
的值换成forwards
。
下图是录制的动画时间轴效果:
现在你可以看到使用animation-fill-mode:forwards;
的效果。当使用这个值时,告诉浏览器动画结束后,元素的样式将设置为动画的最后一帧的样式。如果我们不需要这种方式,希望元素动画结束之后返回到最初状态之前动画效果,那需要点击重置按钮。
backwards
再把animation-fill-mode
的值改成backwards
,看看又会发生什么样的变化。
下图是录制的动画时间轴效果:
注意:看到效果了?这个效果和第一个示例的(animation-fill-mode:none;
)是一样的,那这又是为什么呢?
和forwards
效果不一样,如果设置为backwards
值,那么在动画等待的那段时间内,元素的样式将设置为动画第一帧的样式。在规范中,对backwards
是这样描述的:
During the period defined by
animation-delay
, the animation will apply the property values defined in the keyframe that will start the first iteration of the animation. These are either the values of thefrom
keyframe […] or those of theto
keyframe.
为了说明这一点,对上面的DEMO做了两个修改:
- 在关键帧中的
from
中给球添加了一个不同的颜色 - 在动画中使用
animation-delay
属性添加了一个延迟播放时间
效果如下:
下图是录制的动画时间轴效果:
现在你看到的效果是,如果你一旦点击播放按钮,球体先会变成一个蓝色。这是因为有一个延迟时间。从技术上讲,每一个动画都有一个默认的延迟时间,只不过这个时间是0
而以,所以你并没有看到其中的变化。根据前面对backwards
的描述:动画等待的那段时间内,元素的样式将设置为动画第一帧的样式。这样解释你就应该较为明白,因为我们的示例有一个1s
时间的延迟,这样一来,元素在等待的这1s
时间内,元素的样式就是关键帧(也就是@keyframes
中的frome
或0%
的样式)第一帧中的样式,在这个示例中,球体变成蓝色。然后在1s
时间之后,元素动画效果和之前一样。
说实话,我并没有发现backwards
值有很多实际应用的价值。很难想像在大多数场景动画中,第一帧会有不同的样式风格,而不是在动画前启动前样式。如果你有这方面的实际用例,欢迎分享一下。
both
最后来看一下animation-fill-mode
取值为both
的效果。这个值将会告诉浏览器同时应用forwards
和backwards
两个属性值的效果。言外之意,animation-fill-mode
取值为both
值时,animation-fill-mode
相当于同时配置了backwards
和forwards
,意味着在动画等待和动画结束状态,元素将分别应用动画第一帧和最后一帧的样式。
在Demo中操持同样的样式风格,看看示例中取值为both
时效果会发生什么?
下图是录制的动画时间轴效果:
正如你所见到的,在初始延迟期间,元素样式是动画第一帧样式,然后动画结束之后,元素运用了动画中最后一帧的样式风格。
一些小技巧
基于上述介绍以及规范中的一些细节,在使用animation-fill-mode
时还是需要注意以下几点:
- 虽然
backwards
和both
两值在最后有一些细小的区别,但这些通过JavaScript或者用户的输入在一些复杂的动画场景中可以派上用场。这些用例可能比比皆是(比如游戏中),但只有实验和创新才能让大家更了解其作用。 - 如果你的动画中把
animation-direction
设置为reverse
时将会影响forwards
和backwards
效果。如果你把上面的示例做做修改,你将看到它们是如何工作的。 - 虽然我们在这里说
animation-fill-mode
只接受前面描述的四个值,但在CSS-wide属性值中有些值也可以使用。 - 在早期的规范版本中,
animation-fill-mode
并不是简写属性animation
中的一部分。 - 当在简写的
animation
属性中,自定义的动画名不要和animation-fill-mode
中的值匹配,比如说forwards
,或者和animation-direction
的属性值匹配,比如reverse
。这样浏览器将会把动画名解析为一个animation-fill-mode
的值能够它能够控制元素在动画执行前与动画完成后样式。听起来令人非常困惑,但你会明白我的意思。
总结
我希望这篇文章的总结能更好的帮助你理解这个属性。其实这里面的一些内容也帮助了我更好的理解了它。其实你可以做一些其它的案例来阐述animation-fill-mode
在独特条件下的效果,可以用来修正这篇文章中的不对之处。
后续我们将结合一些其它示例,把animation-fill-mode
结合animation-direction
、animation-duration
、animation-delay
在不同取值下产生的不同效果。感兴趣的同学,欢迎后续文章的更新。当然,如果你有相关的经验,欢迎在下面的评论中与我们一起分享。
本文根据@Louis Lazaris的《Understanding the CSS animation-fill-mode Property》所译,整个译文带有我们自己的理解与思想,如果译得不好或有不对之处还请同行朋友指点。如需转载此译文,需注明英文出处:https://www.sitepoint.com/understanding-css-animation-fill-mode-property/。
如需转载,烦请注明出处:http://www.w3cplus.com/css3/understanding-css-animation-fill-mode-property.html