文档章节

CSS3 transition规范的实际使用经验

lotozhou
 lotozhou
发布于 2015/11/25 09:59
字数 1899
阅读 20
收藏 0

        本篇文章主要讲述CSS3 transition规范和在不同浏览器之间的使用差异,我要谈的是技术背景,主要讨论在使用CSS过渡的过程中所未预料到的问题。
        结构 (HTML),表现(CSS),以及行为(JavaScript)相分离并不是什么新鲜的事情,然而 CSS 能跨越这个界限并且可以在短期内得到实际的应用,这还真的是一个完全不同的讨论话题。

        几周前,我开发一个 JavaScript 模块,在能够使用 CSS 过渡的条件下,JavaScript 端又无法获取到实现过渡的方式。实际遇到的问题是这两者根本没有办法同步,经过多次的测试后,我只能放弃。而我的测试结果正是本文所讲述的。

        首先,我们要说一下getcomputedstyle(),是一种用 JavaScript 返回浏览器渲染CSS的属性值的方法。 这个方法可以查看“DOM Level 2: getComputedStyle()”和“CSS Level 2: Computed Values”。

        这对于像 font-size 这样的属性, 通过一个参数便可以转换为像素值。 但对于可以缩写的属性值,例如 margin ,一些浏览器则返回为空。再就是那些同一属性的不同属性值,例如 font-weight 的值 bold 和700。WebKit也有一个小bug,它会从伪对象中提取出属性值。

        这里所讲述的浏览器之间的差异是2013年1月在使用 Firefox18(Gecko),Opera 12.12 (Presto), Internet Explorer10(Trident),Safari 浏览器6.0.2(WebKit),Chrome 23(WebKit) 以及 Gecko 和 WebKit的 Nightly build channels。


        事不宜迟,让我们来一起看一下规范与实际情况的差异,为了方便,我省略了各浏览器的前缀。在文中我通过创建一个 CSS3 Transitions Test Suite 来发现问题。


1、指定过渡
CSS3 transitions 规范定义了以下四个 CSS 属性:

  • transition-property

  • transition-duration

  • transition-delay

  • transition-timing-function



过渡属性
transition-property 是用来指定当元素其中一个属性改变时执行 transition 效果。系统默认值是 all,这意味着浏览器能够以动画形式呈现所有的可过渡属性(transition-duration持续时间超过0s),该属性支持单个值或以逗号隔开的多个值列表(跟其他所有transition-*属性一样)。

规范规定,一个浏览器应该接受并保存任何它不能识别的属性。因此,下面的例子中将会看到持续2秒的 padding 过渡:

  1. <font face="inherit">transition-property:foobar,padding;

  2. transition-duration:1s,2s;</font>

复制代码

不同于规范的是,上面的情况在 WebKit 下会解析为 transition-property: all。 而 Firefox 和 Opera 会解析为 transition-property: all, padding.

过渡持续时间
transition-duration 属性规定了一个过渡从初始状态到目标状态的持续时间。它接受以秒或毫秒的值(例如,2.3S和2300ms都是指2.3秒)。

尽管规范明确规定了过渡值必须为正数,但 Opera 仍接受-5S的值,至少对于getComputedStyle()来说是这样的。虽然规范中并没有限制属性值的大小,但 Opera 和 IE 不接受低于10ms的值。而 WebKit 在 getComputedStyle()执行中有个小bug,例如:返回值0.009999999776482582s会取代0.01s。


过渡延迟时间
transition-delay 属性规定了在执行一个过渡之前的等待时间,同样使用值。Delay 可以是负值,但这会导致动画无法平滑过渡。

IE 和 Opera 不接受 transition-duration 在-10ms和10ms之间的值。WebKit 的 floating point 也会在这儿出现。


transition-timing-function 属性规定了过渡效果的时间曲线。包括cubic-bezier(x1, y1, x2, y2), step(, start|end),和预先定义的 cubic-bezier 曲线关键词,linear, ease, ease-in, ease-out和ease-in-out。在使用 LEA Verou 特有的 cubic-bezier 曲线编辑器时,cubic-bezier 背后的公式就变得不再重要。尽管 cubic-bezier 曲线会平滑过渡,但是step()函数会在一个固定的间隔跳到下一个值。这样便会产生逐帧动画的效果;如“Pure CSS3 Typing Animation With steps()”。

linear 的计算值通常表示为 cubic-bezier(0, 0, 1, 1)—— WebKit除外。但 WebKit 仍然会返回 cubic-bezier(0.25, 0.1, 0.25, 1),而不是 ease。规范规定 X 值的必须介于0和1之间,y 值可以超过该范围,而WebKit 允许 X 超过此范围,而 Android 浏览器(4.0版本)却混淆了x和y的范围。

2 过渡完成
我前面已经提到了 CSS 过渡异步运行的问题。规范提及了 TransitionEnd 事件允许 JavaScript 与已完成的过渡同步进行。但可恶的是该规范对此并没具体阐述。事实上,它只是简单地说明单个事件会因为已完成过渡的属性而被终止。

规范指出缩写属性(如padding)应为包括其在内的所有属性(padding-top,padding-right,等等)实现过渡,它并没有说哪个属性应该在 TransitionEnd 事件中被具体命名。然而即使过渡被定义为缩写属性(如padding),Gecko,Trident 和 Presto 对于普通书写的子属性(如padding-top)同样可以实现过渡,而 WebKit 则会阻止过渡。 如果你指定 transition-property: padding,WebKit 会为 padding 执行过渡, 但 transition-property: all 这样就会针对 padding-left 执行新的过渡。而当 padding 正执行过渡时, iPhone 6.0.1 的 Safari 浏览器在也可以执行 font-size 和 line-height的过渡。

  1. <font face="inherit">.example{padding:1px;transition-property:padding;transition-duration:1s;}

  2. .example:hover{padding:10px;}</font>

复制代码

以上 CSS 将在不同浏览器下触发不同的 TransitionEnd:

Gecko,Trident,Presto:
padding-top,padding-right,padding-bottom,padding-left

WebKit:
padding

  1. <font face="inherit">.example {padding: 1px;transition-property: all, padding;transition-duration:1s;}

  2. .example:hover{padding:10px;}</font>

复制代码

以上 CSS 将在不同浏览器下触发不同的TransitionEnd:

Gecko,Trident,Presto,WebKit:
padding-top,padding-right,padding-bottom,padding-left

Safari 6.0.1 on iPhone:
padding-top, padding-right, padding-bottom, padding-left, font-size, line-height

你可以指定负值 transition-delay 来“快速实现”转换。但是transition-duration: 1s; transition-delay: -1s; 在 Gecko 和 WebKit 下执行转换并会立即跳转至目标值。而Trident 和 Presto 将不会触发任何事件。

WebKit在 getComputedStyle() 上遇到的浮点问题也同样存在于 TransitionEnd.elapsedTime 中,所有的浏览器如此。 Math.round(event.elapsedTime * 1000) / 1000 可辅助修复。

WebKit 和 IE 浏览器下执行 background-position,会触发对 background-position-x 和 background-position-y 的 TransitionEnd,而不是 background-position 的TransitionEnd。

所以,即使你知道过渡正在执行,你也不能依赖已有的 TransitionEnd.propertyName。尽管你可以编写大量的 JavaScript 来弥补,但在没有对每一个属性进行恰当性能检测的情况下,即使你采用最新方法也将无法实现。

3 过渡属性
规范列出了浏览器支持动画过渡的一些CSS属性。当然也包括CSS2.1的属性。还有一些可以动态变化的新属性,如 Flexible Box Layout

该属性数值类型非常重要。margin-top 接受和值,但根据可过渡CSS属性列表,只有是可实现动画效果。但这并不能让浏览器开发商避开值实现过渡。然而,word-spacing 属性除外。该属性包括值,但没有浏览器能以动画形式显示。

撇开 TransitionEnd 事件,如果在过渡发生的指定时间内,getComputedStyle()值从A变到B,该属性就会从值A过渡为值B。如果没有执行,例如“CSS属性值发生变化”,那么也许应该仔细核查下DOM。setTimeout()的解析度还不够好以达到快速过渡(小于几百毫秒的持续时间),这时候requestAnimationFrame()就是你的帮手。在重绘前会提醒你,并提供了一些中间值供参考。除了opera,其他的都可以支持。


© 著作权归作者所有

共有 人打赏支持
lotozhou
粉丝 9
博文 51
码字总数 51524
作品 0
苏州
程序员
私信 提问
Autoprefixer:一个以最好的方式处理浏览器前缀的后处理程序

Autoprefixer解析CSS文件并且添加浏览器前缀到CSS规则里,使用Can I Use的数据来决定哪些前缀是需要的。 所有你需要做的就是把它添加到你的资源构建工具(例如 Grunt)并且可以完全忘记有CSS...

飞翔的熊blabla
10/09
0
0
【React自制全家桶】八、React动画以及react-transition-group动画库的使用

React动画通常有三种方法实现从易到难为: 1、transition(CSS3自带) 2、animation(CSS3自带) 3、react-transition-group动画库(需要引入插件) 一、transition(CSS3自带) 1、用法示例...

漂泊的雾
08/02
0
0
Autoprefixer:一个以最好的方式处理浏览器前缀的后处理程序

原文出处:css-tricks 译文出处:三桂 Autoprefixer解析CSS文件并且添加浏览器前缀到CSS规则里,使用Can I Use的数据来决定哪些前缀是需要的。 所有你需要做的就是把它添加到你的资源构建工具...

css-tricks
2014/08/26
0
0
总结CSS3新特性(Transition篇)

CSS 过渡(transition), 是 CSS3 规范的一部分, 用来控制 CSS 属性的变化速率。 可以让属性的变化过程持续一段时间,而不是立即生效。比如,将元素的颜色从白色改为黑色,通常这个改变是立即...

贾顺名
2015/07/21
0
0
CSS3 Transitions, Transforms和Animation使用简介与应用展示

一、前言兼目录索引 《天龙八部》里的虚竹小和尚之前可以说是和尚的先进人物与代表模范,各类清规戒律谨记与严守。但是,后来呢,花姑娘送到跟前,什么戒律都成了浮云,禁不住诱惑享乐去了。...

黄金林
2016/12/21
7
0

没有更多内容

加载失败,请刷新页面

加载更多

OSChina 周二乱弹 —— 其实我在地板也睡不着

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @witt-z :分享歌词: 阴天 在不开灯的房间,当所有思绪都一点一点沉淀。 分享莫文蔚的单曲《阴天》: 《阴天》- 莫文蔚 手机党少年们想听歌,...

小小编辑
12分钟前
11
3
微服务分布式事务实现

https://www.processon.com/view/link/5b2144d7e4b001a14d3d2d30

WALK_MAN
今天
3
0
《大漠烟尘》读书笔记及读后感文章3700字

《大漠烟尘》读书笔记及读后感文章3700字: 在这个浮躁的社会里,你有多久没有好好读完一本书了? 我们总觉得自己和别人不一样,所以当看到别人身上的问题时,很少有“反求诸己”,反思自己。...

原创小博客
今天
4
0
大数据教程(9.5)用MR实现sql中的jion逻辑

上一篇博客讲解了使用jar -jar的方式来运行提交MR程序,以及通过修改YarnRunner的源码来实现MR的windows开发环境提交到集群的方式。本篇博主将分享sql中常见的join操作。 一、需求 订单数据表...

em_aaron
今天
3
0
十万个为什么之什么是resultful规范

起源 越来越多的人开始意识到,网站即软件,而且是一种新型的软件。这种"互联网软件"采用客户端/服务器模式,建立在分布式体系上,通过互联网通信,具有高延时(high latency)、高并发等特点...

尾生
今天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部