# CSS动画
## **一、 定义和用法**
一些 CSS 属性是*可以有动画效果的*,这意味着它们可以用于动画和过渡。
动画属性可以逐渐地从一个值变化到另一个值,比如尺寸大小、数量、百分比和颜色。
## **二、浏览器支持**
表格中的数字表示支持该方法的第一个浏览器的版本号。
紧跟在数字后面的 -webkit-, -moz-, 或 -o- 指定了第一个支持该属性的浏览器版本前缀。
![](https://img.kancloud.cn/e5/27/e527271168a59e7dc398f3e34edc5045_1668x272.png)
## **三、Transition**
1. **基本用法**
```
div {
width: 200px;
height: 200px;
background-color: red;
}
div:hover {
width: 500px;
height: 500px;
}
<div>我是一个盒子</div>
```
代码掩饰的是当鼠标放置于div上 div会迅速变大。变大的是瞬间实现的。
使用 ```transition```可以**指定状态变化所需要的时间**
```
div {
width: 200px;
height: 200px;
background-color: red;
transition: 5s;
}
//此时可以发现,div变大的过程中 变化有了时间梯度,即5秒钟变大 不是干蹦效果了
```
可以设置单项的动画效果 如:```div { transition: 5s height; }``` 效果为:高度变化的时候有个平滑的过度,而宽度则还是干蹦变化
2. **transition-delay**
在同一行```transition```中,可以分别指定多个属性,想要的效果是height先发生变化后,width再发生变化,就是为width指定一个delay参数
```div { transition: 5s height, 1s 5s width; }``` [逗号后的第一个参数是动画过渡时间,第二个参数是delay的时间],delay的真正意义就是指定了动画的发生顺序
3. **transtion-timing-function**
transition的状态变化速度(又称timing function),默认不是匀速的,而是逐渐放慢,这叫做```ease```。
```div { transition: 1s ease };```
其他的模式:
```
linear: 匀速
ease-in : 加速
ease-out: 减速
cubic-bezier函数: 自定义速度模式 //贝塞尔曲线
```
贝塞尔曲线
cubic-bezier称为三次贝塞尔曲线,主要是生成速度曲线的函数,规定是```cubic-bezier(<x1>,<y1>,<x2>,<y2>)```
```
//会产生一个最后阶段放大过度然后回缩的效果
div {
transition: 1s height cubic-bezier(.83,.97,.05,1.44);
}
```
![](https://img.kancloud.cn/be/5a/be5a6d5d13e36f8579aa236a554222dc_544x543.png)
![](https://img.kancloud.cn/05/e9/05e9a4abfef0e4ee246589be39704fe1_366x347.png)
>从上图中我们可以看到,cubic-bezier有四个点:
两个默认的,即:P0(0,0),P3(1,1);
两个控制点,即:P1(x1,y1),P2(x2,y2)
注:X轴的范围是0~1,超出cubic-bezier将失效,Y轴的取值没有规定,但是也不宜过大。
我们只要调整两个控制点P1和P2的坐标,最后形成的曲线就是动画曲线。
4. **transition的各个属性**
```
div {
transition: 1s 1s height ease;
}
//还可独立定义各个属性
div {
transtion-property: height; //规定应用过渡效果的CSS属性名称,过度效果通常是用户将鼠标悬浮到元素上时发生
transition-duration: 1s; //过渡效果持续时间
transition-delay: 1s; //过渡延迟时间
transtion-timing-function: ease; //过渡函数
}
```
5. **transition的使用注意**
(1)目前,各大浏览器(包括IE 10)都已经支持无前缀的transition,所以transition已经可以很安全地不加浏览器前缀。
(2)不是所有的CSS属性都支持transition,完整的列表查看[这里](http://oli.jp/2010/css-animatable-properties/),以及具体的[效果](http://leaverou.github.io/animatable/)。
(3)transition需要明确知道,开始状态和结束状态的具体数值,才能计算出中间状态。比如,height从0px变化到100px,transition可以算出中间状态。但是,transition没法算出0px到auto的中间状态,也就是说,如果开始或结束的设置是height: auto,那么就不会产生动画效果。类似的情况还有,display: none到block,background: url(foo.jpg)到url(bar.jpg)等等。
6. **transition的局限**
transition的优点在于简单易用,但是它有几个很大的局限。
(1)transition需要事件触发,所以没法在网页加载时自动发生。
(2)transition是一次性的,不能重复发生,除非一再触发。
(3)transition只能定义开始状态和结束状态,不能定义中间状态,也就是说只有两个状态。
(4)一条transition规则,只能定义一个属性的变化,不能涉及多个属性。
CSS Animation就是为了解决这些问题而提出的。
## 三、**Animation**
1. **基本用法**
首先,animation需要制定动画一个周期持续的时间以及动画效果的名称
```
div:hover {
animation: 1s rainbow;
}
//此代码表示,当鼠标悬停在div上会产生rainbow的动画效果,持续时间为1s。为此,我们还需要使用keyframes关键字,定义rainbow效果
@keyframes rainbow {
0% { background: #c00; }
50% { background: orange; }
100% { background: yellowgreen; }
}
//rainbow效果一共有三个状态,分别为起始(0%)、中点(50%)和结束(100%)。如果有需要,完全可以插入更多状态。
```
**默认情况下,动画只播放一次。加入```infinite```关键字,可以让动画无限次播放。**
~~~css
div:hover {
animation: 1s rainbow infinite;
}
~~~
**也可以指定动画的播放次数**
~~~css
div:hover {
animation: 1s rainbow 3;
}
~~~
2. **animation-fill-mode**
动画结束以后,会立即从结束状态跳回到起始状态。如果想让动画保持在结束状态,需要使用```animation-fill-mode```属性。
~~~css
//forwards表示让动画停留在结束状态
div:hover {
animation: 1s rainbow forwards;
}
~~~
animation-fill-mode还可以使用下列值
>(1)none:默认值,回到动画没开始时的状态。
(2)backwards:让动画回到第一帧的状态。
(3)both: 根据animation-direction(见后)轮流应用forwards和backwards规则。
3. **animation-direction**
动画循环播放时,每次都是从结束状态跳回到起始状态,再开始播放。animation-direction属性,可以改变这种行为。
~~~css
@keyframes rainbow {
0% { background-color: yellow; }
100% { background: blue; }
}
~~~
默认情况是,animation-direction等于normal
~~~css
div:hover {
animation: 1s rainbow 3 normal;
}
~~~
此外,还可以等于取alternate(交替)、reverse(颠倒)、alternate-reverse等值。它们的含义见下图(假定动画连续播放三次)。
![](https://img.kancloud.cn/ea/de/eadeedd2b38e2a12b850f007f81bfea3_700x194.png)
简单说,animation-direction指定了动画播放的方向,最常用的值是normal和reverse。浏览器对其他值的支持情况不佳,应该慎用。
4. **animation的各项属性**
~~~css
div:hover {
animation: 1s 1s rainbow linear 3 forwards normal;
}
~~~
~~~css
div:hover {
animation-name: rainbow;
animation-duration: 1s;
animation-timing-function: linear;
animation-delay: 1s;
animation-fill-mode:forwards;
animation-direction: normal;
animation-iteration-count: 3; //重复次数
}
~~~
5. **keyframes的写法**
keyframes关键字用来定义动画的各个状态,它的写法相当自由。
~~~css
@keyframes rainbow {
0% { background: #c00 }
50% { background: orange }
100% { background: yellowgreen }
}
~~~
~~~css
// 0% 可以用from代表,100%可以用to代表
@keyframes rainbow {
from { background: #c00 }
50% { background: orange }
to { background: yellowgreen }
}
~~~
如果省略某个状态,浏览器会自动推算中间状态,所以下面都是合法的写法。
~~~css
@keyframes rainbow {
50% { background: orange }
to { background: yellowgreen }
}
@keyframes rainbow {
to { background: yellowgreen }
}
~~~
甚至,可以把多个状态写在一行。
~~~css
@keyframes pound {
from,to { transform: none; }
50% { transform: scale(1.2); }
}
~~~
另外一点需要注意的是,浏览器从一个状态向另一个状态过渡,是平滑过渡。steps函数可以实现分步过渡。
~~~css
div:hover {
animation: 1s rainbow infinite steps(10);
}
~~~
这里有一个非常神奇的[例子](http://dabblet.com/gist/1745856),可以看到steps函数的用处。
6. **animation-play-state**
有时,动画播放过程中,会突然停止。这时,默认行为是跳回到动画的开始状态。
如果想让动画保持突然终止时的状态,就要使用```animation-play-state```属性。
~~~css
div {
animation: spin 1s linear infinite;
animation-play-state: paused;
}
div:hover {
animation-play-state: running;
}
//上面的代码指定,没有鼠标没有悬停时,动画状态是暂停;一旦悬停,动画状态改为继续播放。效果如下。
~~~
7. **浏览器前缀**
目前,IE 10和Firefox(>= 16)支持没有前缀的animation,而chrome不支持,所以必须使用webkit前缀。
也就是说,实际运用中,代码必须写成下面的样子。
~~~css
div:hover {
-webkit-animation: 1s rainbow;
animation: 1s rainbow;
}
@-webkit-keyframes rainbow {
0% { background: #c00; }
50% { background: orange; }
100% { background: yellowgreen; }
}
@keyframes rainbow {
0% { background: #c00; }
50% { background: orange; }
100% { background: yellowgreen; }
}
~~~