浏览器渲染过程:javascript
<img>
标签引用了一张图片,向服务器发出请求。此时浏览器不会等到图片下载完,而是继续渲染后面的代码;<div><span><ul><li>
们,“大伙儿收拾收拾行李,咱得从新来过……”,浏览器向服务器请求了新的CSS文件,从新渲染页面。简单来讲,浏览器渲染一共有五步,
1.解析HTML标签,构建DOM树。css
2.解析CSS标签,构建CSSOM树。
咱们已经看到html解析器碰到脚本后会作的事情,接下来咱们看下html解析器碰到样式表会发生的状况
js会阻塞解析,由于它会修改文档(document)。css不会修改文档的结构,若是这样的话,彷佛看起来css样式不会阻塞浏览器html解析。可是事实上 css样式表是阻塞的。阻塞是指当cssom树创建好以后才会进行下一步的解析渲染。html
全部的样式表都会被解析成cssom对象模型(就和dom树同样展示结构),每个页面element都会被许多css规则匹配
- 匹配顺序:origin => weight => specificity
- css origin
-做者自定义
-浏览器使用者定义
-userAgent 定义
- css weight
-normal weight
-!important weight
- css specificity (咱们最应该关注的点)
注意:!important 已经被css的做者引入了浏览器,用来覆盖页面样式。
原本这个方式并非给开发者使用的,在样式表中使用!important 会让咱们忽略specificity 真正工做的原理。
- specificity 是css使人困惑的主要来源。specificity规则由(a,b,c,d)的规则决定。
-a : 值为1(当样式放在style属性中的时候),0为其它状况 -b : id在样式规则中出现的次数 eg:#slide #hello p的值就是2 -c : class,伪类,和属性在样式中出现的次数 eg:input[type=email]值就是2 -d : 标签个数(tag names)和伪类元素出现的次数 例如: Example: HTML <div id=”sidebar”> <div id=”widget” class=”class-div”> <span class=”span-class” style=”color: red”>Hello, world!</span> </div> </div> CSS .span-class { /* Specificity (0, 0, 1, 0) */ color: green; } #sidebar #widget { /* Specificity (0, 2, 0, 0) */ color: orange; } #sidebar { /* Specificity (0, 1, 0, 0) */ color: yellow; } #sidebar .class-div { /* Specificity (0, 1, 1, 0) */ color: blue; } The inline rule, will have a specificity of (1, 0, 0, 0). 接下来的优先级是(0, 2, 0, 0);以此类推 - 使用!important 的样式覆盖均可以经过css优先级机制(好比加个样式等来提升优先级) - 总结: -元素样式的应用按照以下规则排列 -origin -weight -specificity -order of definition specificity只有在origin和weight一致的状况下才有效,再次就是定义的顺序 最后定义的样式会覆盖以前的样式。 - 在解析css的过程当中,cssom树并非浏览器构建的惟一数据结构,css样式匹配是件重活 为了尽量快的加载样式,每一种最精确的匹配规则都会被加入众多哈希表中的一张 。 有针对id,class类名,标签名和一些其余不符合任何规则的哈希表。 当浏览器试图寻找哪一个样式表加载到元素上的时候,它不必查看全部的规则,而只须要查看哈希表。 这又引导咱们到另外一个重要的知识:咱们从一个元素开始,寻找它的id,class,标签等,而后在多个字典中查找他们, 咱们老是匹配**最右边**的(rightmost)的选择器,这个选择器称为**主选择器(key selector).** 这个概念开始的时候可能有些难以理解,可是它对咱们如何写更快的css规则相当重要。 让咱们看个例子: HTML <div id=”container1”> … thousands of <a> elements here … <a> … </a> … thousands of <a> elements here … </div> <div id=”container2”> <a class=”a-class”>...</a> </div> 咱们假如要选择container2种的a标签 This selector: #container2 a {...} 这个选择器将会严重影响加载性能,若是从左到右读取,那就是先找到#container2而后再找a标签 ,然而浏览器将会从右往左读取,它会先读取全部的a标签,而后再沿着dom往上走,直到找到#container. 这意味着这个规则会寻找全部的a,可是实际上不少a在#container1之中。 咱们能够写一个更有效率的样式表:#container2 .a-class {...}。 这个特性能够在javascript或者jquery中获得很好的发挥: eg:将$(‘#container .class-name’)改成$(‘.class-name’, ‘#container’)能够很好的性能。 -前者会先去寻找.class-name而后再沿着dom树寻找#container元素 -后者会先找到#container,而后再沿着子树寻找.class-name的元素
3.把DOM和CSSOM组合成渲染树(render tree)。render树java
4.在渲染树的基础上进行布局,计算每一个节点的几何结构。
布局(layout):定位坐标和大小,是否换行,各类position, overflow, z-index属性 ……
5.把每一个节点绘制到屏幕上(painting),正式开画!jquery