浏览器的渲染步骤
- 根据 HTML 构建 HTML 树 (DOM)
- 根据 CSS 构建 CSS 树 (CSSOM)
- 将两棵树合并成一颗渲染树 (render tree)
- Layout 布局 (文档流、盒模型、计算大小和位置)
- Paint 绘制 (把边框颜色、文字颜色、阴影等画出来)
- Compose 合成 (根据层叠关系展示画面)
如何更新样式?
一般使用 JS 来更新样式
比如 div.style.background = 'red'
比如 div.style.display = 'none'
比如 div.classList.add('red')
比如 div.remove()直接删掉节点
三种不同的渲染样式
- 第一种:全走
JS / CSS > 样式 > 布局 > 绘制 > 合成
如果修改元素的 layout 属性,也就是改变了元素的几何属性(例如宽度、高度、左侧或顶部位置等),那么浏览器将必须检查所有其他元素,然后“自动重排”页面。任何受影响的部分都需要重新绘制,而且最终绘制的元素需进行合成
- 第二种:跳过 layout
JS / CSS > 样式 > 绘制 > 合成
如果修改 paint 属性(例如背景图片、文字颜色或阴影等),即不会影响页面布局的属性,则浏览器会跳过布局,但仍将执行绘制
- 第三种:跳过 layout 和 paint
JS / CSS > 样式 > 合成
如果更改一个既不要布局也不要绘制的属性,则浏览器将跳到只执行合成。
查询不同的CSS属性会触发的不同过程:
CSS 动画优化
JS 优化
使用 requestAnimationFrame 代替 setTimeout 或 setlnterval
CSS 优化
使用 will-change 或 translate
transform 属性
CSS transform 属性允许你旋转,缩放,倾斜或平移给定元素。这是通过修改CSS视觉格式化模型的坐标空间来实现的。
常用功能
- translate 位移
transform: translate(12px, 50%);
transform: translateX(2em);
transform: translateY(3in);
transform: translateZ(2px);
transform: translate3d(12px, 50%, 3em);
translate(-50%,-50%) 可做绝对定位元素的居中
- scale 缩放
transform: scale(2, 0.5);
transform: scaleX(2);
transform: scaleY(0.5);
用的较少,容易出现模糊
- rotate 旋转
transform: rotateX(10deg);
transform: rotateY(10deg);
transform: rotateZ(10deg);
transform: rotate(0.5turn);
transform: rotate3d(1, 2.0, 3.0, 10deg);
一般用于360度旋转制作 loading
- skew 倾斜
transform: skewX(30deg);
transform: skewY(1.07rad);
transform: skew(30deg, 20deg);
- 组合使用
transform: scale(0.5) translate(-100%,-100%);
transform: none;取消所有
transition 属性
transtion 属性是 transition-property,transition-duration,transition-timing-function 和 transition-delay 的一个简写属性,作用是补充中间帧。
- transition-property(属性名)
none
没有过渡动画
all
所有可被动画的属性都表现出过渡动画
IDENT
属性名称。由小写字母
a
到z
,数字0
到9
,下划线(_
)和破折号(-
)。第一个非破折号字符不能是数字。同时,不能以两个破折号开头transtion 属性可以被指定为一个或多个 CSS 属性的过渡效果,多个属性之间用逗号进行分隔
transition-property: none;
transition-property: all;
transition-property: test_05;
transition-property: -specific;
transition-property: sliding-vertically;
transition-property: test1;
transition-property: test1, animation4;
transition-property: all, height, all;
transition-property: all, -moz-specific, sliding;
- transition-duration(时长)
表示过渡属性从旧的值转变到新的值所需要的时间。如果时长是
0s
,表示不会呈现过渡动画,属性会瞬间完成转变。不接受负值
/* <time> 值 */
transition-duration: 6s;
transition-duration: 120ms;
transition-duration: 1s, 15s;
transition-duration: 10s, 30s, 230ms;
- transition-timing-function(过度方式)
liner 此关键字表示定时函数 cubic-bezier(0.0, 0.0, 1.0, 1.0)。使用这个定时函数,动画会以恒定的速度从初始状态过渡到结束状态
ease 此关键字表示定时函数 cubic-bezier(0.25, 0.1, 0.25, 1.0)。 这个函数类似于 ease-in-out, 尽管它在开始时加速地更快,但在接近中间中,加速已经开始变慢了
ease-in 此关键字表示定时函数 cubic-bezier(0.42, 0.0, 1.0, 1.0)。动画开始时缓慢,然后逐步加速,知道达到最后状态,动画突然停止
easy-out 此关键字表示定时函数 cubic-bezier(0.0, 0.0, 0.58, 1.0)。动画开始很快,然后逐渐减慢,直到最终状态
easy-in-out 此关键字表示定时函数 cubic-bezier(0.42, 0.0, 0.58, 1.0)。使用这个定时函数,动画开始的行为类似于 ease-in 函数,动画结束时的行为类似于 ease-out函数
step-start 此关键字表示定时函数 steps(1, start)。使用这个定时函数,动画会立刻跳转到结束状态,并一直停留在结束状态直到动画结束
step-end 此关键字表示定时函数 steps(1, end)。使用这个定时函数,动画会一直保持初始状态直到动画结束,然后立刻跳转到结束状态
transition-timing-function: ease
transition-timing-function: ease-in
transition-timing-function: ease-out
transition-timing-function: ease-in-out
transition-timing-function: linear
transition-timing-function: cubic-bezier(0.1, 0.7, 1.0, 0.1)
transition-timing-function: step-start
transition-timing-function: step-end
transition-timing-function: steps(4, end)
transition-timing-function: ease, step-start, cubic-bezier(0.1, 0.7, 1.0, 0.1)
- transition-delay(延迟)
表明动画效果属性生效之前需要等待的时间
transition-delay: 3s;
transition-delay: 2s, 4ms;
缩写语法
/* Apply to 1 property */
/* property name | duration */
transition: margin-right 4s;
/* property name | duration | delay */
transition: margin-right 4s 1s;
/* property name | duration | timing function */
transition: margin-right 4s ease-in-out;
/* property name | duration | timing function | delay */
transition: margin-right 4s ease-in-out 1s;
/* Apply to 2 properties */
transition: margin-right 4s, color 1s;
/* Apply to all changed properties */
transition: all 0.5s ease-out;
注意
- 并不是所有属性都能过渡
display:none => block 无法过渡,一般改成 visibility:hidden => visible
display: none 是彻底消失,不在文档流中占位,浏览器也不会解析该元素;不会被子元素继承
visibility:hidden 是视觉上消失了,在文档流中占位,浏览器会解析该元素;会被子元素继承
如果想隐藏某元素,但在页面上保留该元素的空间的话,应该使用visibility:hidden,如果想在隐藏某元素的同时让其它内容填充空白的话应该使用display:none
- 过渡必须要有起始,一般只有一次或两次动画,比如 hover 和非 hover 状态的过渡
- 如果除了起始还有中间点,有两种方法
1.使用两次transform
.a === transform ===> .b
.b === transform ===> .c
如何知道到了中间点?
用 setTimeout 或者监听 transitionend 事件
css
#demo{
width: 100px;
height: 100px;
border: 1px solid red;
margin: 50px;
transition: transform 1s linear;
}
#demo.b{
transform: translateX(200px);
}
#demo.c{
transform: translateX(200px) translateY(100px);
js
button.onclick = ()=>{
demo.classList.add('b')
setTimeout(()=>{
demo.classList.remove('b')
demo.classList.add('c')
},1000)
}
2.使用 animation 申明关键帧,添加动画
#demo{
width: 100px;
height: 100px;
border: 1px solid red;
margin: 50px;
transition: transform 1s linear;
}
#demo.start{
animation: xxx 1.5s;
}
@keyframes xxx {
0% {
transform: none;
}
66.66%{
transform: translateX(200px);
}
100%{
transform: translateX(200px) translateY(100px);
}
}
- 如何让动画停在最后一帧?
加上 forwards
#demo{
width: 100px;
height: 100px;
border: 1px solid red;
margin: 50px;
}
#demo.start{
animation: xxx 1.5s forwards;
}
@keyframes xxx {
0% {
transform: none;
}
66.66%{
transform: translateX(200px);
}
100%{
transform: translateX(200px) translateY(100px);
}
}
@keyframes 标准写法
- from to
@keyframes slidein {
from {
transform: translateX(0%);
}
to {
transform: translateX(100%);
}
}
- 百分数
@keyframes identifier {
0% { top: 0; left: 0; }
30% { top: 50px; }
68%, 72% { left: 50px; }
100% { top: 100px; left: 100%; }
}
animation 属性
CSS animation 属性是 animation-name,animation-duration, animation-timing-function,animation-delay,animation-iteration-count,animation-direction,animation-fill-mode 和 animation-play-state 属性的一个简写属性形式。
- animation-name (动画名)
指定应用的一系列动画,每个名称代表一个由@keyframes定义的动画序列
/* Single animation */
animation-name: none;
animation-name: test_05;
animation-name: -specific;
animation-name: sliding-vertically;
/* Multiple animations */
animation-name: test1, animation4;
animation-name: none, -moz-specific, sliding;
- animation-duration(时长)
指定一个动画周期的时长,单位为秒(s)或者毫秒(ms),无单位值无效
animation-duration: 6s
animation-duration: 120ms
animation-duration: 1s, 15s
animation-duration: 10s, 30s, 230ms
- animation-timing-function(过渡方式)
/* Keyword values */
animation-timing-function: ease;
animation-timing-function: ease-in;
animation-timing-function: ease-out;
animation-timing-function: ease-in-out;
animation-timing-function: linear;
animation-timing-function: step-start;
animation-timing-function: step-end;
/* Function values */
animation-timing-function: cubic-bezier(0.1, 0.7, 1.0, 0.1);
animation-timing-function: steps(4, end);
animation-timing-function: frames(10);
/* Multiple animations */
animation-timing-function: ease, step-start, cubic-bezier(0.1, 0.7, 1.0, 0.1);
- animation-delay(延迟)
从动画应用在元素上到动画开始的这段时间的长度,
0s
是该属性的默认值,代表动画在应用到元素上后立即开始执行。定义一个负值会让动画立即开始。但是动画会从它的动画序列中某位置开始。例如,如果设定值为-1s,动画会从它的动画序列的第1秒位置处立即开始
animation-delay: 3s;
animation-delay: 2s, 4ms;
- animation-iteration-count(次数)
动画在结束前运行的次数 可以是1次 无限循环,如果指定了多个值,每次播放动画时,将使用列表中的下一个值,在使用最后一个值后循环回第一个值
/* 值为关键字 */
animation-iteration-count: infinite;
/* 值为数字 */
animation-iteration-count: 3;
animation-iteration-count: 2.4;
/* 指定多个值 */
animation-iteration-count: 2, 0, infinite;
- animation-direction(方向)
动画是否反向播放
normal
每个循环内动画向前循环,换言之,每个动画循环结束,动画重置到起点重新开始,这是默认属性
alternate
动画交替反向运行,反向运行时,动画按步后退,同时,带时间功能的函数也反向,比如,ease-in 在反向时成为ease-out。计数取决于开始时是奇数迭代还是偶数迭代
reverse
反向运行动画,每周期结束动画由尾到头运行
alternate-reverse
反向交替, 反向开始交替
动画第一次运行时是反向的,然后下一次是正向,后面依次循环。决定奇数次或偶数次的计数从1开始
animation-direction: normal
animation-direction: reverse
animation-direction: alternate
animation-direction: alternate-reverse
animation-direction: normal, reverse
animation-direction: alternate, reverse, normal
- animation-fill-mode(填充模式)
动画在执行之前和之后如何将样式应用于其目标
none
当动画未执行时,动画将不会将任何样式应用于目标,而是已经赋予给该元素的 CSS 规则来显示该元素。这是默认值forwards
目标将保留由执行期间遇到的最后一个关键帧计算值。 最后一个关键帧取决于 animation-direction和animation-iteration-count 的值backwards
动画将在应用于目标时立即应用第一个关键帧中定义的值,并在 animation-delay 期间保留此值。 第一个关键帧取决于 animation-direction 的值both
动画将遵循 forwards 和 backwards 的规则,从而在两个方向上扩展动画属性。在 animation-*属性上指定多个以逗号分隔的值时,它们将根据值的数量以不同的方式分配给 animation-name 属性中指定的动画
/* Single animation */
animation-fill-mode: none;
animation-fill-mode: forwards;
animation-fill-mode: backwards;
animation-fill-mode: both;
/* Multiple animations */
animation-fill-mode: none, backwards;
animation-fill-mode: both, forwards, none;
animation-play-state(是否暂停)
一个动画是否运行或者暂停
running
当前动画正在运行
paused
当前动画已被停止
/* Single animation */
animation-play-state: running;
animation-play-state: paused;
/* Multiple animations */
animation-play-state: paused, running, running;
缩写语法
/* @keyframes duration | timing-function | delay |
iteration-count | direction | fill-mode | play-state | name */
animation: 3s ease-in 1s 2 reverse both paused slidein;
/* @keyframes duration | timing-function | delay | name */
animation: 3s linear 1s slidein;
/* @keyframes duration | name */
animation: 3s slidein;
*本文为鲲游北冥的原创文章,著作权归本人和饥人谷所有,转载务必注明来源