1

0、写在前面

CSS系列——一步一步带你认识transition过渡效果这篇文章中,我给大家详细讲解了transition过渡的用法,能够实现比较友好的过渡效果,但是功能比较有限,如果要想实现比较漂亮的动画效果,就需要我们今天要请出主角animation登场了。首先,我们来看看animation的属性:

属性 描述 css
@keyframes 规定动画 3
animation 所有动画属性的简写,除了animation-play-state属性 3
animation-name 规定@keyframes动画的名称 3
animation-duration 规定动画完成一个周期的时间,默认为0 3
animation-timing-function 规定动画的速度曲线,默认是ease 3
animation-iteration-count 规定动画播放的次数,默认是1 3
animation-direction 规定动画是否在下一个周期逆向播放 3
animation-play-state 规定动画是否正在运行或者暂停,默认是running 3
animation-fill-mode 规定动画时间之外的状态 3

哇~~~,这么多,讲的什么鬼啊,算了,不看了!且慢,本文将结合示例来讲解每一个属性,生动易懂。不信?不信你就接着看呗。

1、浏览器支持度

Can I use网站中,我们可以查询到,目前仅IE10以上支持animation属性。Internet Explorer 10、Firefox 以及 Opera 支持 animation 属性。Safari 和 Chrome 支持替代的 -webkit-animation 属性。为了节约篇幅,本文中,所有的示例中将省略浏览器。

2、CSS Animation属性详解

2.1 animation

使用animation需要指定动画的名称以及动画完成一个周期的持续时间。animation是一个复合属性,有以下属性:

animation:<animation-name> || <animation-duration> || <animation-timing-function> || <animation-delay> || <animation-iteration-count> || <animation-direction> ]*

可以单独写每一个属性,也可以直接使用animation复合属性。一般使用复合属性,可以减少代码量,何乐不为呢?

下面将结合示例详细介绍animation每一个属性的功能和用法。

2.2 @keyframes的写法

@keyframes关键字可以用来定义动画的各个状态,基本写法如下:

@keyframes rainbow {
  0% {
    background-color: #cd0000;
  }
  50% {
    background-color: deeppink;
  }
  100% {
    background-color: blue;
  }
}

其中,rainbow是动画的名称。同时,我们也可以使用from代替0%,使用to代替100%,因此上面的写法与下面的写法等同:

@keyframes rainbow {
  from {
    background-color: #cd0000;
  }
  50%{
    background-color: deeppink;
  }
  to {
    background-color: blue;
  }
}

2.3 animation-name

用法:

animation-name: none | NAME[,none | NAME]*;

指定@keyframes后面紧跟的动画的名字,css加载的时候会应用该名字的@keyframes规则来实现动画。默认值为none,此时没有动画效果。

2.4 animation-duration

用法:

animation-duration: <time>[,<time>]*

指定动画持续的时间,默认是0,表示没有动画,单位可以设置成ms或者s。如果忽略时长,则动画不会允许,因为默认值是0。

<div class="demo1"></div>
.demo1{
  width: 100px;
  height: 100px;
  background-color: yellow;
}
.demo1:hover{
  animation: 5s rainbow;
}

@keyframes rainbow {
  0% {
    background-color: #cd0000;
  }
  50%{
    background: deeppink;
  }
  100% {
    background: blue;
  }
}

在浏览器中的效果如下:

在这个例子中,我们指定了动画的名字是rainbow,并且设置了动画持续的时间是5s,动画分为三帧完成。因此,在hover之前,背景颜色是yellow,而在hover的时候,背景突变为 #cd0000,也就是0%的背景颜色;同时在50%的时候背景颜色变成为deeppink,在100%的时候背景颜色变成blue

2.5 animation-timing-function

用法:

animation-timing-function:ease | linear | ease-in | ease-out | ease-in-out | cubic-bezier(<number>, <number>, <number>, <number>) [, ease | linear | ease-in | ease-out | ease-in-out | cubic-bezier(<number>, <number>, <number>, <number>)]*

指定动画播放方式,默认值为ease,支持lineareaseease-inease-outease-in-outcubic-bezier(n,n,n)steps

 <div class="demo2">
   <h3>ease</h3>
   <div class="box box1"></div>
   <h3>linear</h3>
   <div class="box box2"></div>
   <h3>ease-in</h3>
   <div class="box box3"></div>
   <h3>ease-out</h3>
   <div class="box box4"></div>
   <h3>ease-in-out</h3>
   <div class="box box5"></div>
</div>
.box{
  position: relative;
  width: 50px;
  height: 50px;
  color: #fff;
  margin-top: 10px;
}
.box1{
  background-color: red;
  animation: box-a 5s ease;
}
.box2{
  background-color: deeppink;
  animation: box-a 5s linear;
}
.box3{
  background-color: blue;
  animation: box-a 5s ease-in;
}
.box4{
  background-color: darkgreen;
  animation: box-a 5s ease-out;
}
.box5{
  background-color: yellow;
  animation: box-a 5s ease-in-out;
}

@keyframes box-a {
  0%{
    left: 0;
  }
  100%{
    left: 500px;
  }
}

在浏览器中的效果如下:

在这个例子中,我们制定了动画周期过程中的变化曲线,其实和transition中的变化曲线是一样的,分别是:

  • ease 缓慢开始,缓慢结束(默认)
  • ease-in 缓慢开始
  • ease-out 缓慢结束
  • ease-in-out 缓慢开始,缓慢结束(和ease稍有区别,差别并不大)
  • linear 匀速

2.6 animation-delay

用法:

animation-delay: <time>[,<time>]*

指定动画开始播放的延迟时间,默认是0,即立即播放动画,单位可以是ms或者s。

<div class="demo3"></div>
.demo3{
  position: relative;
  width: 50px;
  height: 50px;
  background-color: yellow;
  animation: demo3-a 1s 5s;
}
@keyframes  demo3-a  {
  0%{
    left: 0;
    background-color: deeppink;
  }
  100%{
    left: 500px;
    background-color: blue;
  }
}

在浏览器中的效果如下:

在这个例子中,指定了动画的执行周期是1s,hover的时候,动画并没有立即执行,而是延迟了5s才执行。

2.7 animation-iteration-count

animation-iteration-count:infinite | <number> [, infinite | <number>]*

指定动画播放的次数,默认值为1,表示动画播放完后就停止。除了指定数字,也可以设置关键字infinite,表示无限循环播放。

<div class="demo4"></div>
 .demo4{
        position: relative;
        width: 50px;
        height: 50px;
        background-color: yellow;
        animation: demo4-a 2s 3s 3;
    }
    @keyframes  demo4-a  {
        0%{
            left: 0;
            background-color: deeppink;
        }
        100%{
            left: 500px;
            background-color: blue;
        }
    }

在浏览器中的效果如下:

在这个例子中,我们指定了动画播放的次数是3次,因此,播放3次后动画就停止播放了。如果我们修改一行上面的代码:

animation: demo4-a 2s 3s inifinite;,指定动画无限播放,因此动画会一直播放下去。

利用animation-iteration-count:infinite,我们可以实现一个心脏跳动的效果。html代码不熟悉的可以先不管,直接看css代码。

<div class="heart">
  <svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" viewBox="0 0 500 450">
    <defs>
      <radialGradient id="gradient" cx="35%" cy="30%">
        <stop stop-color="red" />
        <stop stop-color="#900" offset="100%" />
      </radialGradient>
      <radialGradient id="glow">
        <stop stop-color="white" stop-opacity=".8" offset="60%" />
        <stop stop-color="white" stop-opacity="0" offset="100%" />
      </radialGradient>
    </defs>
    <path d="m140,0 c-137.446907,-2.4711 -264.638405,212.481001 105.92601,435.341002c0.405975,-0.730988 1.968994,-0.730988 2.375,0c382.517975,-230.048996 234.665009,-451.640422 92.625977,-434.390902c-55.372986,6.724501 -81.503998,37.456499 -93.813995,63.888002c-12.30899,-26.431503 -38.440002,-57.163502 -93.812988,-63.888002c-4.438004,-0.539301 -8.866013,-0.870199 -13.300003,-0.949999l0,-0.000101z" id="path2361" fill="url(#gradient)"/>
    <circle r="10%" cx="25%" cy="25%" fill="url(#glow)" />
  </svg>
</div>
.heart{
  margin: 100px;
  width: 200px;
  height: 200px;
  animation: pound 1s infinite;
}
@keyframes pound {
  from{
    transform: none;
  }
  to{
    transform: scale(1.2);
  }
}

在浏览器中的效果如下:

在这个例子中,我们指定了动画无限次播放,并且在100%的时候,放大到1.2倍,一个心跳的效果就实现了。是不是很酷?

2.8 animation-direction

用法:

animation-direction: normal | alternate [, normal | alternate]*

指定动画播放的方向,支持normalalternatealternate-reverse关键字。

normal,默认值,表示正常播放动画;

alternate表示轮转正方向播放动画,即在奇数次(1,3,5...)正常播放,而偶数次(2,4,6...)反向播放;

alternate-reversealternate刚好反过来,即在奇数次(1,3,5...)反向播放,而偶数次(2,4,6...)正向播放。

看例子好理解:

<h3>normal</h3>
<div class="box box11"></div>
<h3>alternate</h3>
<div class="box box12"></div>
<h3>alternate-reverse</h3>
<div class="box box13"></div>
.box11{
  background-color: red;
  animation: box-a 5s normal infinite;
}
.box12{
  background-color: deeppink;
  animation: box-a 5s alternate infinite;
}
.box13{
  background-color: blue;
  animation: box-a 5s alternate-reverse infinite;
}
@keyframes box-a {
  0%{
    left: 0;
  }
  100%{
    left: 500px;
  }
}

在浏览器中的运行效果如下:

这个例子就不详细解释了,很简单。利用 animation-direction属性,我们可以实现文字闪烁的效果,看代码:

 <div class="blink">看我闪烁了5次</div>
.blink{
  display: table-cell;
  vertical-align: middle;
  width: 120px;
  height: 50px;
  background-color: deeppink;
  color: #ffffff;
  animation: 0.5s blink-a 5 alternate;
}
@keyframes  blink-a{
  to{
    color: transparent;
  }
}

在浏览器中效果如下:

在这个例子中,我们指定了animation-directionalternate,并且动画运行的次数为5次。

2.9 animation-play-state

animation-play-state:running | paused [, running | paused]*

指定动画播放的状态,支持关键字runningpaused。其中:

running,默认值,表示动画正在播放中;

paused,表示暂停播放。可以在Javascript中使用该属性:object.style.animationPlayState=”paused”来暂停动画。

 <div class="demo5"></div>
.demo5{
  width: 100px;
  height: 10px;
  background-color: deeppink;       
}
.demo5:hover{
  animation: spin 3s linear infinite;      
}
@keyframes spin {
  to{
    transform: rotate(1turn);
  }
}

在浏览器中的效果如下:

在这个例子中,我们指定了动画播放周期为3s,无限循环。当鼠标挪开的时候,动画就会恢复到最初的状态。如果我们想鼠标挪开的时候,保持动画的运行状态怎么办?请看下面:

 .demo5{
        width: 100px;
        height: 10px;
        background-color: deeppink;
        animation: spin 3s linear infinite;
        animation-play-state: paused;
    }
    .demo5:hover{
        animation-play-state: running;
    }
    @keyframes spin {
        to{
            transform: rotate(1turn);
        }
    }

在浏览器中运行的效果如下:

我们稍微修改了css代码,就实现了鼠标挪开的时候,保持动画的播放状态不变。

2.10 animation-fill-mode

指定动画时间外的属性,支持关键字noneforwardsbackwardsboth

none,默认值,表示动画播放完成后,恢复到初始的状态;

forwards,表示动画播放完成后,保持@keyframes里最后一帧的属性;

backwards,表示开始播放动画的时候,应用@keyframes里第一帧的属性,播放完成的时候,恢复到初始状态,通常设置animation-delay后,才能看出效果。

both,表示forwardsbackwards都应用。

请看示例:

<h3>none</h3>
<div class="box"></div>
<h3>forwards</h3>
<div class="box forwards"></div>
<h3>backwards</h3>
<div class="box backwards"></div>
<h3>both</h3>
<div class="box both"></div>
.box{
  position: relative;
  width: 50px;
  height: 50px;
  background-color: deeppink;
  color: #fff;
  margin-top: 10px;
  animation: mode-a 5s 1 2s;
}
.forwards{
  animation-fill-mode: forwards;
}
.backwards{
  animation-fill-mode: backwards;
}
.both{
  animation-fill-mode: both;
}
@keyframes mode-a {
  from {
    left:0;
    background-color: green;
  }
  to{
    left: 500px;
    background-color: blue;
  }
}

说实话,刚开始我不知道这几个属性的区别在哪里,但是当我写了一个demo,然后自己对比发现,哦,也就那样嘛。

动画播放前背景颜色是deeppink

none,在动画播放的一瞬间,动画的背景颜色变成green,播放完成后恢复到初始状态;

forwards在动画播放的一瞬间,动画的背景颜色变成green,播放完成后保持最后一帧的属性,也就是背景颜色保持为blue,因为动画默认播放会恢复到最初状态,所以又会从最初的状态开始播放;

backwards在动画播放的一瞬间,动画的背景颜色变成green,播放完成后保持初始状态,也就是背景颜色保持为deeppink

backwards兼顾了forwardsbackwards的属性,在动画播放的一瞬间,应用backwards属性,动画的背景颜色变成green,播放完成后应用forwards的属性,播放完成后保持最后一帧的属性,也就是背景颜色保持为blue

3、写在最后

好了,animation属性的介绍就到这里了。animation每一个属性并不难理解,难的是我们如何使用这些属性写出很酷炫的动画效果?任何事情都不是一蹴而成的,多思考,多写,这就是秘诀。

最后推荐一个很有名的动画库animate.css以及loading效果

感谢阅读!

参考

  1. CSS动画简介
  2. CSS3 animation介绍
  3. W3school

遇见了,不妨关注下我的微信公众号「前端Talkking


micstone
1.6k 声望151 粉丝

一个喜欢用文字记录成长过程的程序员