🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
# 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; } } ~~~