关于CSS Transition,你需要知道的事
CSS3的过渡属性,给web应用带来了简单优雅的动画,但是比起初次相见,他(transition)有许多细则。
在这片文章中,我将会专研CSS3的过渡(transition)中更加复杂的部分,从链式和事件到硬体加速和动画函数。
让浏览器控制动画序列,通过改变帧率,减少绘画和减少GPU的工作,能够优化性能和效率。
应用 transition
一个最简单使用transition的方法就是和CSS伪元素一起用,比如:hover。注意我们在指定属性名字,transition的时长,以及默计时函数,linear。
.element {
height: 100px;
transition: height 2s linear;
}
.element:hover {
height: 200px;
}
当:hover伪元素被激活的时候,这高度会动态地在两秒内从100px过度到200px。
duration是唯一在transition缩写中需要的项目。浏览器默认的定时方法是ease,以及一个all的属性,除非他们已经提供了。
当谈论到激活transition,我们不希望被限制于使用伪元素 —— 很显然这不灵活。解决这个的方法就是用程序添加和删除class
/* CSS */
.element {
opacity: 0.0;
transform: scale(0.95) translate3d(0,100%,0);
transition: transform 400ms ease, opacity 400ms ease;
}
.element.active {
opacity: 1.0;
transform: scale(1.0) translate3d(0,0,0);
}
.element.inactive {
opacity: 0.0;
transform: scale(1) translate3d(0,0,0);
}
// JS with jQuery
var active = function(){
$(.element).removeClass(inactive).addClass(active);
};
var inactive = function(){
$(.element).removeClass(active).addClass(inactive);
};
以上的列子,我们用了2个不同的过渡(transition),当激活的时候,元素向上滑动,当无效化之后,淡出。所有的javascript所做的事就是切换active 和 inactive这两个class。
过渡渐变
不是所有的CSS属性都能过渡,最基本的规则是你只能过渡绝对值。比如,你不能让height从 0px过渡到auto,浏览器不能计算中间过度值,因此属性变化是瞬间的。Oli Studholme提供了便利的 一份完全过度属性的列表。
同时,有一些很好的解决方法。第一个方法包括添加透明度到渐变,然后过渡到背景色。比如:
.panel {
background-color: #000;
background-image: linear-gradient(rgba(255, 255, 0, 0.4), #FAFAFA);
transition: background-color 400ms ease;
}
.panel:hover {
background-color: #DDD;
}
如果渐变是持续的,你可以过渡background-position,就像这里写的,否则,你的最后手段是创建两个元素,一个放在另一个之上,然后过渡你的透明度。
.element {
width: 100px;
height: 100px;
position: relative;
background: linear-gradient(#C7D3DC,#5B798E);
}
.element .inner {
content: ;
position: absolute;
left: 0; top: 0; right: 0; bottom: 0;
background: linear-gradient(#DDD, #FAFAFA);
opacity: 0;
transition: opacity 1s linear;
}
.element:hover .inner {
opacity: 1;
}
后者方法的需要注意的是,这需要额外的标记,并且在内部的div能够捕捉到指针事件。伪元素,类似:before和:after可以是过度理想的使用案例。
硬体加速
过渡某个属性,比如left和margin会导致浏览器每帧都会重新计算样式。这消耗相当昂贵,并且可能会导致不必要的重绘,特别是如果你在屏幕上有很多元素。这在低性能设备上显得特别明显,比如手机。
这个解决方案是使用CSS过渡来减少渲染给GPU带来的压力。简单来说,这在过渡的时候,将元素变成了一张图片,避免任何样式重新计算,这极大程度上增加了性能。一个简单强迫浏览器用硬体渲染一个元素的方法是,设置转型的Z轴,这个你可以用translate3d:
transform: translate3d(0,0,0);
不过这不是根治性能的方法,并且会带来许多本身的问题。只有当需要的时候,你才应该用硬体加速,并且完全不需要在每个元素上都使用它。
比如,硬体加速会导致微妙的字体问题,比如一个字体出现的时候失去了加粗效果。这是因为一个bug,当元素开启硬体加速的时候,不支持子像素抗锯齿。你可以看到在两个渲染模式下的一个清晰的差别。