本文主要讲述 CSS 动画相关的知识,包括浏览器渲染原理、使用 CSS 动画的两种方式(transition 和 animation)以及自己学习 CSS 的一点心得
1. 浏览器渲染原理
浏览器渲染过程包括:
根据 HTML 构建 HTML 树 ( DOM )
根据 CSS 构建 CSS 树( CSSOM )
将两棵树合并成一颗渲染树( render tree )
Layout 布局(文档流、盒模型、计算大小和位置)
Paint 绘制(把边框颜色、文字颜色、阴影等画出来)
Compose 合成(根据层叠关系展示画面)
DOM 和 CSSOM 合并为渲染树时,因为 DOM 中的头部是不出现在页面中的,所以 DOM 的头部不会参与两颗树的合并。DOM 和 CSSOM 将相同的元素合并在一起,不同的元素各自归结到它们的父节点上,最终合并成了 render tree
但是每次改变属性不一定都需要完整的走完上述的六个步骤,改变某个属性浏览器的更新方式可以分为三种:
JS/CSS -> Stle -> Layout -> Paint -> Composite
JS/CSS -> Stle -> Paint -> Composite
JS/CSS -> Stle -> Composite
当我们使用 div.remove() 时就会使用第一种更新方式;改变背景颜色时会使用第二种更新方式;改变 transform 时会使用第三种更新方式。每个属性的改变和更新方式之间的联系是不确定的,如果想要确定某个属性对应哪种更新方式可以使用以下的网站 CSS Triggers
2. 使用 CSS 动画的两种方式
2.1 transform
在使用 transition 和 animation 时一般我们都需要使用都 transform ,所以我们需要先学习一下 transform 。 transform 常用的功能有四个:位移 translate 、缩放 scale 、旋转 rotate 、倾斜 skew 。具体的使用方式建议查看 transform MDN
需要注意的是,inline 元素不支持 transform ,需要先变成 block
2.2 transition
transition 用于补充中间帧,可以用于改变大小、透明度、是否可视、背景颜色时的过渡,具体的使用方式建议查看 transition MDN
需要注意的是,并不是所有属性都能过渡,例如 display: none; 变成 display: block; 是无法过渡的;且过渡必须要有起始状态
如果除了起始状态外还有其他状态,我们可以多次使用 transform ,然后通过 setTimeout 函数或者监听 transitioned 事件来改变属性的状态
2.3 animation
animation 可用于声明关键帧和添加动画,是多个 animation 相关属性的一个简写属性形式,具体的使用方式建议查看 animation MDN
animation 缩写语法为 animation: 时长 过渡方式 延迟 次数 方向 填充模式 是否暂停 动画名,这些属性都有其对应的单独属性。使用 animation 时,如果想让动画停留在最后一帧可以在 animation 中加 forwards
如果 animation 除了起始状态外还有其他状态,那么可以通过 @keyframes 结合使用,具体的使用方法建议看 @keyframes MDN
下面我们通过让一个 div 进行移动来看看这两种动画如何实现, div 的移动路径为
( 0 ,0 )-> ( 100px , 0 )-> ( 100px , 100px )
transition 动画的 HTML 、CSS 和 JavaScript 代码
开始
复制代码#demo{
width: 100px;
height: 100px;
border: 1px solid red;
margin: 50px;
transition: transform 1s linear;
}
#demo.b{
transform: translateX(100px);
}
#demo.c{
transform: translateX(100px) translateY(100px);
}
复制代码button.onclick = ()=>{
demo.classList.add('b')
setTimeout(()=>{
demo.classList.remove('b')
demo.classList.add('c')
},1000)
}
复制代码
当我们点击开始按钮时,b 类就被加入到 div 中,一秒后 div 到达 ( 100px , 0)的位置,同时触发器生效,将 b 类移除并加入 c 类,这时候 div 便向下移动 100px 到达 ( 100px , 100px )
animation 的 CSS 和 JavaScript 代码 ( HTML 部分的代码相同)
#demo{
width: 100px;
height: 100px;
border: 1px solid red;
margin: 50px;
transition: transform 1s linear;
}
#demo.start{
animation: xxx 1.5s forwards;
}
@keyframes xxx {
0% {
transform: none;
}
50%{
transform: translateX(100px);
}
100%{
transform: translateX(100px) translateY(100px);
}
}
复制代码button.onclick = ()=>{
demo.classList.add('start')
}
复制代码
当我们点击开始按钮时,start 类就被加入到 div 中,然后就开始按照 @keyframes 进行插帧,50% 时在( 100px , 0)处,100% 时在( 100px , 100px)处
通过上面的代码可以看出,要实现多个动作的时候 animation 的代码会更简单一些
3. 学习 CSS 的心得
学习 CSS 与学习 HTML 一样,要自己多动手去实现,同时要多参考别人的实现思路,只要能满足自己想实现的样式即可,前端最重要的还是 JavaScript ,我们应该把更多的时间花在 JavaScript 上而不是 CSS。