理解animation-fill-mode属性

编辑推荐: 掘金是一个高质量的技术社区,从 CSS 到 Vue.js,性能优化到开源类库,让你不错过前端开发的每一个技术干货。 点击链接查看最新前端内容,或到各大应用市场搜索「 掘金」下载APP,技术干货尽在掌握中。

我相信很多前端开发人员都有基于CSS @keyframes创建动画的经历。甚至其中有很多人创建了一些很复杂的动效和去实验这个特性。

如果你想要全面了解这篇文章将要介绍的内容,建议你花点时间阅读我2011年在Smashing Magazine介绍的一个主题,这篇文章也是非常不错的。不过,在今天这篇文章中,我并不想介绍有关于CSS动画中所有的属性,我只想专注于CSS动画中的一个属性:animation-fill-mode属性。

这个动画属性对动画影响并不很明显。例如没有人会对CSS动画中animation-nameanimation-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属性可以接受noneforwardsbackwards或者both四个值中的一个值。接下来分别来解释每个值对其影响。

none

noneanimation-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 the from keyframe […] or those of the to keyframe.

为了说明这一点,对上面的DEMO做了两个修改:

  • 在关键帧中的from中给球添加了一个不同的颜色
  • 在动画中使用animation-delay属性添加了一个延迟播放时间

效果如下:

下图是录制的动画时间轴效果:

现在你看到的效果是,如果你一旦点击播放按钮,球体先会变成一个蓝色。这是因为有一个延迟时间。从技术上讲,每一个动画都有一个默认的延迟时间,只不过这个时间是0而以,所以你并没有看到其中的变化。根据前面对backwards的描述:动画等待的那段时间内,元素的样式将设置为动画第一帧的样式。这样解释你就应该较为明白,因为我们的示例有一个1s时间的延迟,这样一来,元素在等待的这1s时间内,元素的样式就是关键帧(也就是@keyframes中的frome0%的样式)第一帧中的样式,在这个示例中,球体变成蓝色。然后在1s时间之后,元素动画效果和之前一样。

说实话,我并没有发现backwards值有很多实际应用的价值。很难想像在大多数场景动画中,第一帧会有不同的样式风格,而不是在动画前启动前样式。如果你有这方面的实际用例,欢迎分享一下。

both

最后来看一下animation-fill-mode取值为both的效果。这个值将会告诉浏览器同时应用forwardsbackwards两个属性值的效果。言外之意,animation-fill-mode取值为both值时,animation-fill-mode相当于同时配置了backwardsforwards,意味着在动画等待和动画结束状态,元素将分别应用动画第一帧和最后一帧的样式。

在Demo中操持同样的样式风格,看看示例中取值为both时效果会发生什么?

下图是录制的动画时间轴效果:

正如你所见到的,在初始延迟期间,元素样式是动画第一帧样式,然后动画结束之后,元素运用了动画中最后一帧的样式风格。

一些小技巧

基于上述介绍以及规范中的一些细节,在使用animation-fill-mode时还是需要注意以下几点:

  • 虽然backwardsboth两值在最后有一些细小的区别,但这些通过JavaScript或者用户的输入在一些复杂的动画场景中可以派上用场。这些用例可能比比皆是(比如游戏中),但只有实验和创新才能让大家更了解其作用。
  • 如果你的动画中把animation-direction设置为reverse时将会影响forwardsbackwards效果。如果你把上面的示例做做修改,你将看到它们是如何工作的。
  • 虽然我们在这里说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-directionanimation-durationanimation-delay在不同取值下产生的不同效果。感兴趣的同学,欢迎后续文章的更新。当然,如果你有相关的经验,欢迎在下面的评论中与我们一起分享。

本文根据@Louis Lazaris的《Understanding the CSS animation-fill-mode Property》所译,整个译文带有我们自己的理解与思想,如果译得不好或有不对之处还请同行朋友指点。如需转载此译文,需注明英文出处:https://www.sitepoint.com/understanding-css-animation-fill-mode-property/

大漠

常用昵称“大漠”,W3CPlus创始人,目前就职于手淘。对HTML5、CSS3和Sass等前端脚本语言有非常深入的认识和丰富的实践经验,尤其专注对CSS3的研究,是国内最早研究和使用CSS3技术的一批人。CSS3、Sass和Drupal中国布道者。2014年出版《图解CSS3:核心技术与案例实战》。

如需转载,烦请注明出处:http://www.w3cplus.com/css3/understanding-css-animation-fill-mode-property.html

返回顶部