transition从效果上看是一种平滑过渡的动画,本质上是在线性时间内将属性从开始值过渡到结束值。例如获得焦点,点击鼠标等动作导致CSS属性值的变化是瞬间完成的,感觉有点生硬。用transition可以指定在某时间段内将属性值平滑过渡,增强用户体验。

  • 4个子属性
  • transition-property
  • transition-duration
  • transition-timing-function
  • transition-delay
  • 触发过渡的方式
  • transitionend事件
  • 隐式过渡
  • 开关过渡和永久过渡
  • auto过渡

4个子属性

transition有4个子属性:transition-property,transition-duration,transition-timing-function,transition-delay

transition-property指定需要过渡的CSS属性。并不是所有属性都能过渡的,只有能数字量化的CSS属性才能过渡。

哪些属于能数字量化的CSS属性呢?例如:

颜色系,如color,background-color,border-color,outline-color

数字系,实在太多了,如width,height,top,right,bottom,left,zoom,opacity,line-height,background-position,word-spacing,font-weight,vertical-align,outline-outset,z-index等。

01系,如visibility(0表示隐藏,1表示显示)

还有更多如渐变,阴影等分类请参照W3C的Animation of property types,不一一列举了。

W3C上还有可过渡属性一览表Properties from CSS。通常只要能设数字(包括%百分比)的属性都能过渡。

除了单个指定属性外,transition-property还能设为all,表示所有属性都将获得过渡效果。

transition-duration过渡需要的时间,单位可指定s秒,也可指定ms毫秒。默认值是0,表示立刻变化。

如果设置了多个过渡属性,但每个属性的过渡时间都一样,你没必要为transition-duration设多个值,只有设一个即可,该值会应用到所有过渡属性上。

transition-timing-function过渡函数,有lineareaseease-inease-outease-in-outcubic-bezier(n,n,n,n)steps

其实它们都是贝赛尔曲线。如下

 

看贝赛尔曲线就知道了,linear是匀速过渡,ease是先快再慢的节奏,ease-in是加速冲刺的节奏,ease-out是减速到停止的节奏,ease-in-out是先加速后减速的节奏。

现在动画的精度越来越高,如果预定义好的这些函数满足不了你的需求,可以通过cubic-bezier(n,n,n,n)自定义平滑曲线。

从上面的图形中观察到,贝塞尔曲线有4个点,左下为起始点P0坐标固定为(0,0),右上为终点P3坐标固定为(1,1),中间有两点P1和P2的坐标就是cubic-bezier(n,n,n,n)的参数。

通过4条连起来的直线,生成平滑的曲线。一图胜千言:

 
 
 
 
 
 
 
 

如果要凭脑子空写出贝赛尔函数的代码,可能比较困难。好在不用你自己去计算,可以到工具网站(如贝赛尔立方)上自动生成想要效果的代码。

你也可以在该站点上,体验一把lineareaseease-inease-outease-in-out间的差异。

steps可以把过渡阶段分割成等价的几步。什么意思呢?一图胜千言:

 

steps函数有两个参数,第一个参数是分割的数量,第二个参数可选,是关键字startend,不设的话默认是end

因此steps(4, start)等价于step-start(4)steps(4, end)等价于step-end(4)。例如steps(4, end)并非像贝塞尔曲线那样平滑过渡,
相当于将过渡过程从头至尾分成4步,在每一步瞬间完成过渡。最上面的例子中已经有所展示,很容易理解

transition-delay延迟开始过渡的时间,默认值是0,表示不延迟,立即开始过渡动作。单位是s秒或ms毫秒。

w3cschool上没说的是,该属性还能设负时间,意思是让过渡动作从该时间点开始启动,之前的过渡动作不显示。

你可以单独指定这4个子属性,也可以像background等属性一样,合并在transition属性里指定。

但合并时要注意,因为有transition-duration和transition-delay都是时间,浏览器会根据先后顺序,将第一个时间认作为transition-duration,第二个时间认作为transition-delay。

是分开或者合并指定并无标准答案。分开指定可能代码易读性高一点。

但当页面需要适应各浏览器时,每个都要加上-ms-,-moz-等前缀,代码会变的很多,合并在一起代码稍微少点。

另外也可以同时指定多个过渡效果,例如transition: background 1s linear 2s, border-radius 2s ease-in 3s;

触发过渡的方式

常见的就是伪类触发:hover,:focus,:active,:checked等。还有例如@media媒体查询,根据设备大小,横屏竖屏切换时触发。

还有如click,keydown等JS事件触发。页面加载也能触发就不一一列举了。总之过渡的本质是在时间段内平滑过渡属性值,与怎么触发没有关系。

transitionend事件

transition既然涉及时间,自然就有事件。参照MDN有transitionend事件,顾名思义就是过渡结束时触发该事件。但该事件比较坑。例如过渡padding时,代码如下:

#tempDiv {
padding: 1px;
transition-property: padding;
transition-duration: 1s;
}
#tempDiv:hover {
padding: 5px;
}
function showMessage() {
console.log('finished'); //过渡结束时触发打印log
}
var element = document.getElementById("tempDiv");
element.addEventListener("transitionend", showMessage, false);

你可以代码贴到浏览器里试试,结果出现4条log。

因为过渡属性指定的是padding,所以在padding-top,padding-right,padding-bottom,padding-left过渡结束时均触发了transitionend事件。因此log被打印了4次。

如果上述CSS中将transition-property: padding;改为all,同样会触发4次。

除非你改成transition-property: padding-top;这样才能只触发一次,但现实中只过渡一边的场景非常少,通常都是4边同时过渡,

因此例如padding,margin,border之类的属性,用transitionend事件会有多次捕捉的情况发生。

隐式过渡

transition过渡时有时会出现一些比较暧昧的情形,比如设成em的属性,如你所知em是根据font-size来计算的。

类似还有rem,vh,vw等都是根据另一个属性的值来计算得到它的值。

举个例子padding:2em;,如果font-size被改变了,此时padding的“书面值”不变,仍旧是2em,但“实际值”将会发生变化并触发transition过渡。这被称作“隐式过渡”。

多数浏览器会实现隐式过渡,但传闻IE很特别,具体有多特别我也没试过。没试过就轻信传闻好像很不严谨,但根据IE过往的口碑,我宁可信其有…前端工程师都懂的。

开关过渡和永久过渡

开关过渡,顾名思义就是触发源的事件结束后会恢复到原始状态。永久过渡就是过渡后不恢复到原始状态。

上面的例子都是开关过渡,当鼠标hover事件结束后,图片恢复原始尺寸。但永久过渡的话,鼠标hover事件结束后,图片仍旧保持放大后的尺寸。

//开关过渡
.transition {
transition: all 1s ease-in-out;
}
.transition:hover {
transform: scale(1.5);
}
//永久过渡
.forever {
transition: all 1s ease-in-out 999999s;
}
.forever:hover {
transform: scale(1.5);
transition: all 1s ease-in-out;
}

因为回到原始尺寸的transition-duration被设成了一个很大的时间,999999s差不多有12天,理论上你页面开12天就能看到关闭过渡的效果,但现实等于永久过渡。该技巧无需任何JS脚本。

auto过渡

通常我们属性过渡时,都是定值到定值的过渡,例如width:100px过渡到200px。但要过渡到width:auto就不行了。

就算你指定transition: width 1s linear;会发现根本不会有1秒的平滑的过渡效果,而是瞬间完成过渡。

.div1 {
background-color: red;
width: 100px;
height: 50px;
}
#box1:hover {
width: auto;
transition: width 1s linear;
}
<div id="box1" class="div1"></div>

如果想要过渡效果,必须将auto转换为固定值。那么问题来了,如何转换呢?

需要靠JS,通过getComputedStyle获取auto后的固定值后,通过style设置该值,然后再触发CSS的过渡效果。

window.onload = function(){
var box = document.getElementById("box2"),
originWidth = box.clientWidth,
width2AutoLater = null,
width2OriginLater = null; var width2Auto = function(element, time) {
if (typeof window.getComputedStyle == "undefined") return; var width = window.getComputedStyle(element).width;
element.style.width = "auto";
var targetWidth = window.getComputedStyle(element).width;
element.style.width = width;
setTimeout(function() {
element.style.transition = "width "+ time +"ms linear";
element.style.width = targetWidth;
}, 10);
}; var width2Origin = function(element, time) {
setTimeout(function() {
element.style.transition = "width 0s linear";
element.style.width = originWidth + "px";
}, 10);
}; function callLater(func, paramA, paramB){
return function(){
func.call(this, paramA, paramB);
};
} width2AutoLater = callLater(width2Auto, box, 1000);
width2OriginLater = callLater(width2Origin, box, 1000); box.addEventListener("mouseenter", width2AutoLater);
box.addEventListener("mouseleave", width2OriginLater);
}
<div id="box2" class="div1"></div>

代码耐心看看应该能看明白。无CSS,全靠JS实现过渡效果。

思路:给div注册了mouseenter和mouseleave事件来模拟hover效果。

mouseenter绑定width2Auto函数,函数里临时将div的width设为auto后,用getComputedStyle得到宽度值,将该宽度值和transition设进该div的style里。

mouseleave绑定width2Origin函数,函数里将div的width改回初始值。

因为注册事件的函数addEventListener的第二个参数是回调函数名,不能给回调函数传参数。

因此,使用闭包的特性,定义了callLater中间函数,函数里通过call调用上述两个函数。

CSS3 transition介绍的更多相关文章

  1. 【转】CSS3 transition规范的实际使用经验

    原文转自:http://blog.jobbole.com/56243/ 本篇文章主要讲述CSS3 transition规范和在不同浏览器之间的使用差异,关于具体解决方法或如何规避问题的意见可以参考另一 ...

  2. CSS3 transition规范的实际使用经验

    本篇文章主要讲述CSS3 transition规范和在不同浏览器之间的使用差异,关于具体解决方法或如何规避问题的意见可以参考另一篇非常有见地的文章,“All You Need to Know Abou ...

  3. css3 transition animation nick

    时光转眼即逝,又到周六了,今天写点某部分人看不起的css玩玩! 转换 转换属性transform: 浏览器前缀: -webkit-transform;-o-transform;-moz-transfo ...

  4. css3 transition属性

    最近打算学习css3知识,觉得css3写出来的效果好炫好酷,之前一直想要学习来着.可能之前的决心,毅力,耐心不够,所以想要重整起来,放下浮躁的心态,一步一个脚印,踏踏实实的来学习. 首先学习的是css ...

  5. css3 Transition动画执行时有可能会出现闪烁的bug

    css3 Transition动画执行时有可能会出现闪烁的bug,一般出现在开始的时候. 解决方法: 1.-webkit-backface-visibility: hidden; 2.-webkit- ...

  6. CSS3 transition 属性过渡效果 详解

    CSS3 transition 允许 CSS 元素的属性值在一定的时间区间内平滑地过渡.我们可以在不使用 Flash 动画或 JavaScript 的情况下,在元素从一种样式变换为另一种样式时为元素添 ...

  7. CSS3 & transition & animation

    CSS3 & transition & animation https://developer.mozilla.org/en-US/docs/Web/CSS/transition-ti ...

  8. css3简单介绍

    关于css3我先介绍几个简单的选择器: 先进行设置: 字符串匹配属性选择器: E[alt^="a"]  选择属性中以a开头的元素: E[alt$="a"]  选 ...

  9. CSS3 transition/transform

    Transition 1.简写属性transition,可以包括四个属性,这四个属性的顺序按照下面介绍的顺序书写,即transition:property duration timing-functi ...

随机推荐

  1. TortoiseGit学习系列之TortoiseGit基本操作修改提交项目(图文详解)

    前面博客 TortoiseGit学习系列之TortoiseGit基本操作克隆项目(图文详解) TortoiseGit基本操作修改提交项目 项目克隆完成后(可以将克隆 clone 理解为 下载,检出 c ...

  2. ZOJ 2971 Give Me the Number

    Give Me the Number Numbers in English are written down in the following way (only numbers less than  ...

  3. unity多线程

    多线程概念 多线程,是指实现多个线程并发执行的技术,合理利用多线程可以提升程序的性能,在unity中,一般是避免使用多线程的,unity对多线程的支持并不友好. 协程概念 协程,是指在主线程运行时开启 ...

  4. select2插件改造之设置自定义选项 源码

    改造特性: 适应业务需要,选项里面包含“其他”其它”,可以点击填写并设置自定义选项 效果图: 具体代码不做阐述,如有类似需求,请私信.主要源码: /* Copyright 2012 Igor Vayn ...

  5. [译]用R语言做挖掘数据《五》

    介绍 一.实验说明 1. 环境登录 无需密码自动登录,系统用户名shiyanlou,密码shiyanlou 2. 环境介绍 本实验环境采用带桌面的Ubuntu Linux环境,实验中会用到程序: 1. ...

  6. [转]bootstrap-datetimepicker 火狐浏览器报错

    本文转自:https://segmentfault.com/a/1190000008457568 使用bootstrap-datetimepicker日期选择插件时发现在火狐浏览器下报错: 未压缩版报 ...

  7. 使用重绘项美化WinForm中的控件

    如果你觉得项目中的ComboBox.ListBox或其它的Winforms控件不能满足你的显示要求,包括窗体在内很多控件都支持重绘修改显示样式.下面的示例完成对ComBox数据项的重绘,希望能起到抛砖 ...

  8. 分布式ID生成器PHP+Swoole实现(上) - 实现原理

    1.发号器介绍 什么是发号器? 全局唯一ID生成器,主要用于分库分表唯一ID,分布式系统数据的唯一标识. 是否需要发号器? 1)是否需要全局唯一. 分布式系统应该不受单点递增ID限制,中心式的会涉及到 ...

  9. groovy动态类型--能力式设计

    动态类型 动态类型中的类型是在运行时推断的,方法及其参数也是在运行时检查的. 能力式设计 被称作鸭子模式:他有这么一个观点:如果它走路像鸭子,叫起来也像鸭子,那么他就是一只鸭子. 契约式设计 相当于J ...

  10. Redis实现分布式锁2

    redisTemplate实现分布式锁 /** * 分布式锁-加锁 * @param key * @param value 当前时间+超时时间 System.currentTimeMillis()+t ...