浏览器的解析原理
浏览器工作流程
先来个流程图,让大家心里有个底:
从上图,我们能看到这几点:
- 浏览器会解析
- HTML生成DOM Tree
- CSS生成Style Rules
- 解析完成后,浏览器引擎会通过DOM Tree 和 CSS Rule Tree 来构造 Render Tree(渲染树)。注意:Render Tree 渲染树并不等于DOM树,因为head元素和一些display:none的元素没有放在渲染树中
浏览器解析
有下面的HTML示例如下:
<html>
<body>
<div class =“err” id =“div1”>
<p>
这是一个
<span class =“big”>大错误</span>
这也是一个
<span class =“big”>非常大的错误</span>错误
</p>
</div>
<div class =“err” id =“div2”>另一个错误</div>
</body>
</html>
然后我们的CSS文档是这样的:
/*1.*/ div {margin:5px; color:black}
/*2.*/ .err {color:red}
/*3.*/ .big {margin-top:3px}
/*4.*/ div span {margin-bottom:4px}
/*5.*/ #div1 {color:蓝色}
/*6.*/ #div2 {color:green}
于是我们的CSS Rule Tree是这样:
注意:CSS匹配HTML元素是一个相当复杂和有性能问题的事情。所以,你就会在N多地方看到很多人都告诉你,DOM树要小,CSS尽量用id和class,千万不要过渡层叠下去,……
通过这两个树,我们可以得到一个叫Style Context Tree,也就是下面这样(把CSS Rule结点Attach到DOM Tree上):
这个时候就有必要说下这个CSS选择器特性了
选择器特性
CSS选择器由CSS2规范定义如下:
- 如果声明来自是“样式”属性,则计数1,否(= a)
- 计数选择器中的ID属性数(= b)
- 计数选择器中其他属性和伪类的数量(= c)
- 计数选择器中元素名称和伪元素的数量(= d)
连接四个数字abcd(在具有大基数的数字系统中)具有特异性。
这个四个数字保持的优先级是:a>b>c>d
您需要使用的数字基数由您在其中一个类别中的最高数量定义。
例如,如果a = 14,您可以使用十六进制基数。在不太可能的情况下,您将需要一个17位数的基数。后来的情况可能会发生在这样的选择器:html body div div p …(你的选择器中的17个标签不太可能)。
一些例子:
* {} / * a = 0 b = 0 c = 0 d = 0 - > specificity = 0,0,0,0 * /
li {} / * a = 0 b = 0 c = 0 d = 1 - >specificity= 0,0,0,1 * /
li:first-line {} / * a = 0 b = 0 c = 0 d = 2 - > specificity = 0,0,0,2 * /
ul li {} / * a = 0 b = 0 c = 0 d = 2 - > specificity = 0,0,0,2 * /
ul ol + li {} / * a = 0 b = 0 c = 0 d = 3 - > specificity = 0 ,0,0,3 * /
h1 + * [rel = up] {} / * a = 0 b = 0 c = 1 d = 1 - > specificity = 0,0,1,1 * /
ul ol li.red {} / * a = 0 b = 0 c = 1 d = 3 - > specificity = 0,0,1,3 * /
li.red.level {} / * a = 0 b = 0 c = 2 d = 1 - > specificity = 0,0,2,1 * /
#test {} / * a = 0 b = 1 c = 0 d = 0 - > specificity = 0,1,0,0 * /
style =“”/ * a = 1 b = 0 c = 0 d = 0 - > specificity = 1,0,0,0 * /
参考地址: