1. CSS 选择器的优先级是如何计算的?
浏览器通过优先级规则,判断元素展示哪些样式。优先级通过 4 个维度指标确定,我们假定以a、b、c、d命名,分别代表以下含义:
a表示是否使用内联样式(inline style)。如果使用,a为 1,否则为 0。
b表示 ID 选择器的数量。
c表示类选择器、属性选择器和伪类选择器数量之和。
d表示标签(类型)选择器和伪元素选择器之和。
优先级的结果并非通过以上四个值生成一个得分,而是每个值分开比较。a、b、c、d权重从左到右,依次减小。判断优先级时,从左到右,一一比较,直到比较出最大值,即可停止。所以,如果b的值不同,那么c和d不管多大,都不会对结果产生影响。比如0,1,0,0的优先级高于0,0,10,10。
当出现优先级相等的情况时,最晚出现的样式规则会被采纳。如果你在样式表里写了相同的规则(无论是在该文件内部还是其它样式文件中),那么最后出现的(在文件底部的)样式优先级更高,因此会被采纳。
在写样式时,我会使用较低的优先级,这样这些样式可以轻易地覆盖掉。尤其对写 UI 组件的时候更为重要,这样使用者就不需要通过非常复杂的优先级规则或使用!important的方式,去覆盖组件的样式了。
2.实现动画效果方法与requestAnimationFrame
Javascript 中可以通过定时器 setTimeout 来实现,css3 可以使用 transition 和 animation 来实现。html5 还提供一个专门用于请求动画的API,那就是 requestAnimationFrame,顾名思义就是请求动画帧。
- setTimeout:通过设定间隔时间来不断改变图像位置,达到动画效果。但是容易出现卡顿、抖动的现象;原因是:1、settimeout任务被放入异步队列,只有当主线程任务执行完后才会执行队列中的任务,因此实际执行时间总是比设定时间要晚;2、settimeout的固定时间间隔不一定与屏幕刷新时间相同,会引起丢帧。
- requestAnimationFrame:优势:由系统决定回调函数的执行时机。60Hz的刷新频率,那么每次刷新的间隔中会执行一次回调函数,不会引起丢帧,不会卡顿
关于BFC详解
BFC(Block formatting context)直译为”块级格式化上下文”。它是一个独立的渲染区域。
我们一般利用这个去处理一个BFC的外部浮动,或者内部浮动,以及margin重叠等问题。最关键的原则就是体现BFC布局规则第五条:
BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。
当BFC外部存在浮动时,它不应该影响BFC内部Box的布局,BFC会通过变窄,而不与浮动有重叠。 同样的,当BFC内部有浮动时,为了不影响外部元素的布局,BFC计算高度时会包括浮动的高度。 避免margin重叠也是这样的一个道理。
清除浮动的几个例子
.floatfix{
*zoom:1;
}
.floatfix:after{
content:"";
display:table;
clear:both;
}
清除内部浮动
<style>
.par {
border: 5px solid #fcc;
width: 300px;
overflow: hidden; // 生成了一个BFC, 清除内部浮动
}
.child {
border: 5px solid #f66;
width:100px;
height: 100px;
float: left;
}
</style>
<body>
<div class="par">
<div class="child"></div>
<div class="child"></div>
</div>
</body>
清除外部浮动(自适应两栏布局)
<style>
body {
width: 300px;
position: relative;
}
.aside {
width: 100px;
height: 150px;
float: left;
background: #f66;
}
.main {
height: 200px;
background: #fcc;
}
</style>
<body>
<div class="aside"></div>
<div class="main"></div>
</body>
盒模型
- W3C 标准盒模型:
属性width,height只包含内容content,不包含border和padding。 - IE 盒模型:
属性width,height包含border和padding,指的是content+padding+border。
标准盒模型盒子的宽度为: margin+border+padding+content
怪异盒模型盒子的宽度为: css设置的width值,相当于动态计算content的宽度
可通过CSS的box-size
属性设置为content-box
(标准盒模型)或border-box
(IE盒模型或怪异盒模型)
回流与重绘
- 浏览器会把HTML解析成DOM,把CSS解析成CSSOM,DOM和CSSOM合并就产生了Render Tree
- 有了RenderTree,我们就知道了所有节点的样式,然后计算他们在页面上的大小和位置,最后把节点绘制到页面上
- 由于浏览器使用流式布局,对Render Tree的计算通常只需要遍历一次就可以完成,但table及其内部元素除外,他们可能需要多次计算,通常要花3倍于同等元素的时间,这也是为什么要避免使用table布局的原因之一
重点: 回流必将引起重绘,重绘不一定会引起回流
回流 (Reflow)
当Render Tree中部分或全部元素的尺寸、结构、或某些属性发生改变时,浏览器重新渲染部分或全部文档的过程称为回流。
重绘 (Repaint)
当页面中元素样式的改变并不影响它在文档流中的位置时(例如:color、background-color、visibility等),浏览器会将新样式赋予给元素并重新绘制它,这个过程称为重绘
性能影响
回流比重绘的代价要更高。
有时即使仅仅回流一个单一的元素,它的父元素以及任何跟随它的元素也会产生回流
优化
- css层面
- 避免使用table布局。
- 尽可能在DOM树的最末端改变class。
- 避免设置多层内联样式。
- 将动画效果应用到position属性为absolute或fixed的元素上。
- 避免使用CSS表达式(例如:calc())。
- javascript层面
- 避免频繁操作样式,最好一次性重写style属性,或者将样式列表定义为class并一次性更改class属性。
- 避免频繁操作DOM,创建一个documentFragment,在它上面应用所有DOM操作,最后再把它添加到文档中。
- 也可以先为元素设置display: none,操作结束后再把它显示出来。因为在display属性为none的元素上进行的DOM操作不会引发回流和重绘。
- 避免频繁读取会引发回流/重绘的属性,如果确实需要多次使用,就用一个变量缓存起来。
- 对具有复杂动画的元素使用绝对定位,使它脱离文档流,否则会引起父元素及后续元素频繁回流。