[CSS]CSS动画与transform属性

3,843 阅读5分钟

前言

随著对产品要求的提高,如今几乎所有的页面都会用到动画的效果。目的在于提高用户浏览页面的体验,为了实现页面的动画,前端的技术也在不停的演。从最早的用jq操作dom,到CSS3之后的CSS动画。开发者可用的选择越来越多。我们今天就来讨论一下CSS动画的内容。

为什么要用CSS动画?

要实现页面的动画效果,我们本质上要做的其实是让页面上的元素,可以动起来。因此早期的开发者就想到了用dom的api直接操作元素的样式。配合定时器的使用,我们实现了最早的页面动画。到jq推出动画api之后,更是让动画的开发成本大幅下降。

那么既然jq的动画以及如此成熟了,为什么我们还要谈CSS动画?

这其实涉及到浏览器的显示机制,整体很复杂,大家有兴趣的可以自行查阅相关的资料。这里可以简单说一下, 我们的电脑屏幕是有刷新率的,就是我们常说的xxhz。浏览器本身是可以让页面的内容与电脑屏幕的帧数同步显示的。但是当我们用了定时器+原生dom的动画api之后。如果定时器的频率与屏幕显示的频率不同(而且浏览器的定时器并不是准确的),就会在视觉上出现掉帧等情况。

而如果改用CSS动画的话,浏览器本身是可以帮助我们同步动画显示和屏幕的频率的。因此我们发现css动画总会比js动画更加流畅。

如何实现CSS动画

CSS3之后我们有了专门的动画属性,可以直接通过css实现动画效果。不需要再调用dom api。

transition

【transition】是过渡的意思,可以让一个元素的css属性的展示是逐渐形成的。

/* 使用 */
transition: property duration timing-function delay;
/* 示例 */
.box {
        width: 200px;
        height: 200px;
        transition: width 1s;
        background-color: blue;
}
.box:hover {
        width: 100px;
}

如上方的css内容,我们定义了一个class为box的元素,并初始时width是200px。当我们hover的时候,width会变成100px。这样的话平常我们鼠标移上去的时候,元素的宽会突然减少一半。但当我们加上transition之后,这个宽度减少的过程就会变成是渐进的了。

更多内容可以查阅:developer.mozilla.org/zh-CN/docs/…

animation

【animation】是动画,通过animation可以高自由地自定义css动画。

/* 使用 */
animation: name duration timing-function delay iteration-count direction;
/* 示例 */
@keyframes widen {
        from {
          width: 100px;
        }
        to {
          width: 200px;
        }
}
.box {
        width: 200px;
        height: 200px;
        animation: widen 2s ease;
        animation-fill-mode: forwards;
        background-color: blue;
}

观察上方例子,我们可以发现使用animation的时候,我们可以先通过@keyframs 声明一个自定义的动画,再通过animation属性使用。

更多内容可以查阅:developer.mozilla.org/zh-CN/docs/…

transform

【transform】是转化,可以实现旋转,缩放,倾斜或平移等动画效果,甚至3D效果。

/* 使用 */
transform: none|transform-functions;
/* 示例 */
.box {
        width: 200px;
        height: 200px;
        transition: transform 1s linear;
        background-color: blue;
}
.box:hover {
        transform: scaleX(0.5);
}

通过示例代码,我们其实可以观察到transform的设计概念倾向的是元素的转化,而不是单纯的属性变化。像示例中的把宽度从200px变成100px。我们实际的做法是让元素横向缩小一半。

更多内容可以查阅:developer.mozilla.org/zh-CN/docs/…

为什么说transform是特别?

相信不少的朋友在平常看文章或者做面试题的时候都会遇到,单独把transform拿出来讨论的情况。为什么同样是css动画的实现手动,但transform的待遇好像总是是特别的?

其实这是由浏览器的实现决定的。无论是transition还是animation,都只是浏览器帮助我们实现css属性的动态改变,并根据屏幕帧率实现更自然的动画效果。但本质上css的属性改变还是会触发页面的【重绘】【重排】,因此他们的渲染成本是比较高的。

然而transform的待遇则更高级,由于transform可能涉及3D的动画效果,浏览器会为transform的元素单独生成一个图层,并使用GPU进程单独渲染。因此但触发transform效果的时候,是不会影响主图层的,因此不会触发重绘和重排,效率更高。

同时,由于transform的内容是GPU进程渲染的,所以即使浏览器渲染进程阻塞了,我们会发现transform的动画仍然会正常运行。

顺道提一下will-change

我们会发现will-change往往是配合transform使用的。那么will-change究竟是什么东西?其实它还是一个实验中的功能,因此短时间内渲染大量的复杂页面动画可能会让浏览器表现的“措手不及”,这时候如果要优化这个过程,我们可以通过will-change,这个属性来显式地告诉浏览器,我们会用到什么css属性,让浏览器提前准备。

由于transform的渲染会让浏览器临时生成一个图层,这样的话是涉及进程切换的,有一定的成本。通过will-change可以让浏览器提前准备好,进而提升体验。

/* 使用 */
will-change: property
/* 示例 */
.box {
    width: 200px;
    height: 200px;
    transition: transform 1s linear;
    background-color: blue;
		will-change: transfrom;
}
.box:hover {
     transform: scaleX(0.5);
}

更多内容可以查阅:developer.mozilla.org/zh-CN/docs/…

总结

今天我们了解了CSS动画的由来,以及对比js动画,它的优势是什么。然后我们讲了如今主流的3个实现CSS动画的属性,并着重讲述了transform的优势和原理。最后提到了will-change的作用。希望可以对大家对css动画的理解有帮助。

参考

www.jianshu.com/p/8a21deb5e…

www.cnblogs.com/www-123456/…

developer.mozilla.org/zh-CN/docs/…

developer.mozilla.org/zh-CN/docs/…

developer.mozilla.org/zh-CN/docs/…

developer.mozilla.org/zh-CN/docs/…