CSS 过渡

transition 是 CSS3 中具有颠覆性的特征之一,可以让前端开发者不使用flash动画或Javascript的情况下,当元素从一种样式变换为另一种样式时为元素添加效果。在 CSS3 中使用 transition 可以实现补间动画(过渡效果),并且当前元素只要有 “属性” 发生变化,即存在两种状态时,就可以实现平滑的过渡。

帧动画,通过一帧一帧的画面按照固定顺序和速度播放,如电影胶片。

过渡属性 transition

[ transition 多值! ] transition 是一个复合属性,通过 4 个子属性的配合来完成一个完整的过渡效果。

transition: <single-transition>[,<single-transition>]*        // 如果有多维属性变化,可以用逗号隔开

           <single-transition>:                  // 简写属性,用于在一个属性中设置 4 个过渡属性
                   <transition-property>:规定应用过渡的CSS属性的名称(要过渡的属性); 
                || <transition-duration> :定义过渡效果花费的时间,默认为0s(过渡持续的时间);
                || <transition-timing-function> :定义元素过渡属性随时间变化的过渡速度变化效果,默认为ease(过渡时间函数);
                || <transition-delay>:规定过渡效果何时开始,默认为0s(延迟时间);
                
       即,要过渡的属性  过渡持续的时间  过渡时间函数  何时开始(延迟时间)

注意:
  1. IE9-不支持,safari3.1-6、IOS3.2-6.1、android2.1-4.3需添加-webkit-前缀;而其余高版本浏览器支持标准写法。
  2. 过渡transition的这四个子属性只有 <transition-duration> 是必需值且不能为0。
  3. <transition-duration> 和 <transition-delay>都是时间:
        当两个时间同时出现时,第一个是<transition-duration>,第二个是<transition-delay>;
        当只有一个时间时,它是<transition-duration>,而<transition-delay>为默认值0。

// 代码示例:为了方便演示采用hover切换两种状态,但并不仅仅局限于hover状态来实现过渡。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        div{
            width: 100px;
            height: 100px;
            background-color: pink;
            transition: width 5s ease 0;        // 写在div中,而不是hover中,因为有效果差异
        }
        div:hover{
            width: 500px;

        }
    </style>
</head>
<body>
    <div></div>
</body>
</html>

[1] 过渡属性 transition-property

transition-property: none | all | <transition-property>[,<transition-property>]*

   none: 没有指定任何样式
   all: 默认值,表示指定元素所有支持transition-property属性的样式
   <transition-property>: 可过渡的样式,可用逗号分开写多个样式

[ 可过渡的样式 ] 不是所有的CSS样式值都可以过渡,只有具有中间值的属性才具备过渡效果。

Vstart = 开始值; Vend = 结束值; Vres = 中间值; p = 过渡函数的输出值
Vres = (1 - p) * Vstart + p * Vend
当Vres具有有效值时,则该CSS样式可过渡
颜色: color background-color border-color outline-color
位置: backround-position left right top bottom
长度: 
    [1]max-height min-height max-width min-width height width
    [2]border-width margin padding outline-width outline-offset
    [3]font-size line-height text-indent vertical-align  
    [4]border-spacing letter-spacing word-spacing
数字: opacity visibility z-index font-weight zoom
组合: text-shadow transform box-shadow clip
其他: gradient

[2] 过渡持续时间 transition-duration: <time>[,<time>]*                 // 该属性的单位是 s 或 ms

  • 该属性不能为负值;
  • 若该属性为0s,则为默认值;若为0则为无效值,所以必须带单位;
  • 该值为单值时,即所有过渡属性都对应同样时间;该值为多值时,过渡属性按照顺序对应持续时间。

[3] 过渡时间函数 transition-timing-function: <timing-function>[,<timing-function>]*

过渡时间函数共三种取值,分别是:关键字、steps(步进)函数和bezier函数(贝塞尔曲线)。

[ 关键字 ] 关键字,其实是 bezier 函数 或 steps 函数的特殊值

ease:        默认值,开始和结束慢,中间快。相当于cubic-bezier(0.25,0.1,0.25,1)
linear:      匀速。相当于cubic-bezier(0,0,1,1)
ease-in:     开始慢。相当于cubic-bezier(0.42,0,1,1)
ease-out:    结束慢。相当于cubic-bezier(0,0,0.58,1)
ease-in-out: 和ease类似,但比ease幅度大。相当于cubic-bezier(0.42,0,0.58,1)
step-start:  直接位于结束处。相当于steps(1,start)
step-end:    位于开始处经过时间间隔后结束。相当于steps(1,end)

[ steps 步进函数 ]将过渡时间划分成大小相等的时间时隔来运行。

steps(<integer>[,start | end]?)

<integer>:用来指定间隔个数,该值只能是正整数;
第二个参数: 可选,默认是end,表示开始值保持一次;若参数为start,表示开始不保持

[ 贝塞尔曲线 ] 贝塞尔曲线通过 p0-p3 四个控制点来控制,其中p0表示(0,0),p3表示(1,1)。

而<transition-timing-function>就是通过确定p1(x1,y1)和p2(x2,y2)的值来确定的。

transition-timing-function: cubic-bezier(x1,y1,x2,y2);        

// x1,y1,x2,y2都是0到1的值(包括0和1)

[4] 过渡延迟时间 transition-delay: <time>[,<time>]*                 // 该属性的单位是 s 或 ms

  • 该属性若为负值,无延迟效果,但过渡元素的起始值将从0变成设定值( 设定值=延迟时间+持续时间 );
    • 若设定值小于等于0,则无过渡效果;若设定值大于0,则过渡元素从该设定值开始完成剩余的过渡效果。
  • 若该属性为0s,则为默认值;若为0则为无效值,所以必须带单位;
  • 该值为单值时,即所有过渡属性都对应同样时间;该值为多值时,过渡属性按照顺序对应持续时间。

过渡阶段

过渡阶段?↓ ,即 transition 的触发方式。一般分为三种:伪类触发、媒体查询触发 和 Javascript触发。

[1] 伪类触发:hover、:focus、:active 等

  • hover:鼠标悬停触发
  • focus:获得焦点时触发
  • active:用户单击元素并按住鼠标时触发

[2] @media触发:符合媒体查询条件时触发

/* 把浏览器的宽度拖动到小于1000px时触发 */
@media (max-width: 1000px){
    .test{
        width: 500px;
    }
}

[3] 点击事件:用户点击元素时触发                                                       // transition API?↓

test.onclick = function(){
    test.style.width = '300px';
    setTimeout(function(){
        test.style.width = '100px';
    },3000);
}