| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1385 人关注过本帖
标题:CSS3 transition规范的实际使用经验
取消只看楼主 加入收藏
elsyyzh
Rank: 1
来 自:湖北黄冈
等 级:新手上路
帖 子:29
专家分:0
注 册:2015-11-9
结帖率:0
收藏
 问题点数:0 回复次数:0 
CSS3 transition规范的实际使用经验
本篇文章主要讲述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 过渡:
<font face="inherit">transition-property:foobar,padding;
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的过渡。
<font face="inherit">.example{padding:1px;transition-property:padding;transition-duration:1s;}
.example:hover{padding:10px;}</font>

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

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

WebKit:
padding
<font face="inherit">.example {padding: 1px;transition-property: all, padding;transition-duration:1s;}
.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,其他的都可以支持。
搜索更多相关主题的帖子: transition 浏览器 文章 技术 开发 
2015-11-27 15:21
快速回复:CSS3 transition规范的实际使用经验
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.016995 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved