β

理解animation-fill-mode属性

W3CPlus 68 阅读

我相信很多前端开发人员都有 基于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 the from keyframe […] or those of the to 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/

大漠

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

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

作者:W3CPlus
原文地址:理解animation-fill-mode属性, 感谢原作者分享。

发表评论