前言

通过transition,可以让前端开发人员不需要javascript就可以实现简单的动画交互效果。过渡属性看似简单,但实际上它有很多需要注意的细节和容易混淆的地方。

属性

1
2
3
4
transition-property: 过渡属性(默认值为all)
transition-duration: 过渡持续时间(默认值为0s)
transiton-timing-function: 过渡函数(默认值为ease函数)
transition-delay: 过渡延迟时间(默认值为0s)

注意: IE9-不支持该属性,safari3.1-6、IOS3.2-6.1、android2.1-4.3需要添加-webkit-前缀;而其余高版本浏览器支持标准写法

  • 过渡属性 transition-property

    • none: 没有指定任何样式

    • all: 默认值,表示指定元素所有支持transition-property属性的样式

    • transition-property:可过渡的样式,可用逗号分开写多个样式

      不是所有的CSS样式值都可以过渡,关于可过渡的样式总结:

      • 颜色: color background-color border-color outline-color
      • 位置: backround-position left right top bottom
      • 长度: max-height min-height max-width min-width height width border-width margin padding outline-width outline-offset font-size line-height text-indent vertical-align border-spacing letter-spacing word-spacing
      • 数字: opacity visibility z-index font-weight zoom
      • 组合: text-shadow transform box-shadow clip
      • 其他: gradient
  • 过渡持续时间transition-duration

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

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

    过渡时间函数共三种取值,分别是关键字、steps函数和bezier函数

    • steps函数

      steps([,start | end]?)::用来指定间隔个数(该值只能是正整数),第二个参数: 该参数可选,默认是end,表示开始值保持一次;若参数为start,表示开始不保持

    • 贝塞尔曲线

      cubic-bezier(x1,y1,x2,y2):贝塞尔曲线通过p0-p3四个控制点来控制,其中p0表示(0,0),p3表示(1,1)。

    • 关键字

      • 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)

复合属性

过渡transition的这四个子属性只有transition-duration是必需值且不能为0。其中,transition-durationtransition-delay都是时间。当两个时间同时出现时,第一个是transition-duration,第二个是transition-delay;当只有一个时间时,它是transition-duration,而transition-delay为默认值0

transition: <transition-property> || <transition-duration> || <transition-timing-function> || <transition-delay>

注意: transition的这四个子属性之间不能用逗号隔开,只能用空格隔开。因为逗号隔开的代表不同的属性(transition属性支持多值,多值部分稍后介绍);而空格隔开的代表不同属性的四个关于过渡的子属性;

多值

transition的多个属性值用逗号分隔开表示可以同时为多个值设置过渡属性

  • 若不同的transition-property值,对应的transition-delay | transition-timing-function | transition-duration的属性值都相同时,则对应的这些属性设置一个即可

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    .test1{
    transition-property: width, background;
    transition-delay: 200ms;
    transition-timing-function: linear;
    transition-duration: 2s;
    }
    /*类似于*/
    .test2{
    transition: width 2s linear 200ms, background 2s linear 200ms;
    }
  • 当transition-property值的个数多于对应的transition-delay | transition-timing-function | transition-duration的属性值(属性值的个数大于1个)时,将按顺序开始取值

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    .test1{
    transition-property: width,background,opacity;
    transition-duration: 2s,500ms;
    transition-timing-function: linear,ease;
    transition-delay: 200ms,0s;
    }
    /*类似于*/
    .test2{
    transition: width 2s linear 200ms,background 500ms ease 0s,opacity 2s linear 200ms;
    }
  • 当transition-property值的个数少于对应的transition-delay | transition-timing-function | transition-duration的属性值个数时,多余的属性值将无效

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    .test1{
    transition-property: width;
    transition-duration: 2s,500ms;
    transition-timing-function: linear,ease;
    transition-delay: 200ms,0s;
    }
    /*类似于*/
    .test2{
    transition: width 2s linear 200ms;
    }
  • 当transition-property的值中出现一个无效值,它依然按顺序对应transition的其他属性值(其他属性出现无效值,处理情况也类似)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    .test1{
    transition-property: width,wuxiao,background;
    transition-duration: 2s,500ms;
    transition-timing-function: linear,ease;
    transition-delay: 200ms,0s;
    }
    /*类似于*/
    .test2{
    transition: width 2s linear 200ms,background 2s linear 200ms;
    }
  • 当transition-property的值中,有些值重复出现多次,则以最后出现的值为准,前面所有出现的值都被认定为无效值,但依然按顺序对应transition的其他属性值

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    .test1{
    transition-property: width,width,background;
    transition-duration: 2s,500ms;
    transition-timing-function: linear,ease;
    transition-delay: 200ms,0s;
    }
    /*类似于*/
    .test2{
    transition: width 500ms ease 0s,background 2s linear 200ms;
    }

过渡阶段

  • 过渡开始时间=样式改变的时刻+过渡延迟时间;而过渡结束时间=过渡开始时间+过渡持续时间
  • 过渡起始值=过渡前的过渡属性值;而过渡结束值=过渡完成后的过渡属性值
  • 过渡分为两个阶段:前进(forward)和反向(reverse)。若前进阶段进行一段时间后进入反向阶段,则反向阶段的初始值是前进阶段结束时的瞬时值
  • 以hover为例,若在元素非hover态时设置transition,相当于设置的反向状态。而前进和反向是一致的。而如果在元素hover态设置transition,则前进状态以hover态设置的为准,而反向状态以非hover态设置的为准
  • 如果子元素和父元素过渡属性都一致。若触发子元素过渡时,父元素正在过渡,则将父元素过渡的中间态的值作为子元素过渡的初始值
  • 若过渡起始值或过渡开始值为auto,则浏览器不会自己计算成具体数字值,而是不发生过渡效果。所以要过渡某些属性,首先需要将其重置成具体数字值
  • 隐式过渡是指一个属性改变时引起另一个属性的改变。如border-width是1em,则font-size改变时,border-width也会相应的改变。firefox和IE浏览器支持隐式过渡。而webkit内核浏览器不支持隐式过渡。

触发方式

一般地,过渡transition的触发有三种方式,分别是伪类触发、媒体查询触发和javascript触发。其中常用伪类触发包括:hover、:focus、:active等

  • hover: 鼠标悬停触发

  • active: 用户单击元素并按住鼠标时触发

  • focus: 获得焦点时触发

  • @media: 符合媒体查询条件时触发

  • 点击事件: 用户点击元素时触发

transition事件

关于过渡transition的事件只有一个,是transitionend事件,它发生在过渡事件完成后

transitionEnd的事件对象具有以下3个私有属性:

  • propertyName:发生transition效果的CSS属性名

  • elapsedTime:代表发生实际效果的持续时间。若完整进行,则返回完整时间;若中途中断,则返回实际时间

  • pseudoElement:如果transition效果发生在伪元素,会返回该伪元素的名称,以“::”开头。如果不发生在伪元素上,则返回一个空字符串’’

    注意:

  • 若transition效果发生在伪元素上,IE浏览器将不会触发transitionEnd事件

  • 过渡分为两个阶段:前进阶段和反向阶段。transitionend事件在前进阶段结束时会触发,在反向阶段结束时也会触发

  • 过渡事件触发的次数与transition-property过渡属性的个数有关。过渡属性有几个就会触发几次

  • 如果过渡属性是复合属性,如border-width相当于是border-top-width、border-bottom-width、border-left-width和border-right-width这四个属性的集合。则过渡事件触发4次

  • 如果过渡属性是默认值all,则过渡事件的次数是计算后的非复合的过渡属性的个数。如果发生过渡的属性是border-width和width,则经过计算后过渡事件应该触发5次

  • 如果过渡延迟时间为负值,且绝对值大于等于过渡持续时间时,低版本webkit内核浏览器不会产生过渡效果,但会触发过渡事件;而其他浏览器即不会产生过渡效果,也不会触发过渡事件

  • 如果过渡属性存在复合属性及该复合属性包含的非复合属性,则浏览器计算复合属性的子属性时,不会重复计算已包含的属性

    1
    2
    3
    4
    5
    6
    7
    .test{
    border: 1px solid black;
    transition:border-width 1s,border-left-width 2s;
    }
    .test:hover{
    border-width:10px;
    }