CSS

浏览器渲染CSS背后发生的事

本文将简单介绍浏览器如何渲染CSS,并介绍CSS引擎背后的工作原理

Posted by lijiahao on August 26, 2017

CSS是Cascading Style Sheets(层叠样式表)的简称,是一种用来为结构化文档(如HTML文档或XML应用)添加样式(字体、间距和颜色等)的计算机语言。了解过CSS或写过CSS的都知道,CSS非常容易上手,只要知道你需要渲染的HTML标签元素,就可以通过element { propety: style }的形式给元素增加样式,那么浏览器是如何识别各类CSS样式,如何将样式应用到标签元素上的呢?今天将从浏览器背后的CSS引擎了解CSS的渲染原理。

浏览器引擎之CSS引擎

当浏览器展示一个静态页面在我们面前时,是浏览器引擎将.html文件和.css文件经过一系列的处理后作为像素级画面展示在屏幕上。每个浏览器都有属于自己的浏览器引擎,在Chrome里面是Blink,在Edge里面是EdgeHTML,在Safari里面是Webkit,在Firefox里面是Gecko。

1

如上图所示,为了将HTML文件和CSS文件转化为像素画面,浏览器引擎需要做以下事:

HTML编译——>将CSS规则和DOM元素对应——>解析盒模型的布局——>组织盒模型布局——渲染展示

下面对这些流程做简单的介绍

1.HTML编译

将HTML解析成浏览器可以理解的语言,也就是将HTML的各个节点解析成一个DOM树,DOM树包含了各个节点的父子关系,不过此时因为还没应用CSS样式规则,各个DOM节点还不知道自己长什么样。

2

2.将CSS规则和DOM元素对应

为了将CSS规则和DOM元素对应,此时就需要CSS引擎排上用场了。通过CSS引擎,每个DOM节点和CSS样式规则相对应,也就CSS引擎将样式规则作为一个计算属性应用在DOM树上对应的节点:

3

3.解析盒模型布局

将DOM节点解析成盒模型,也就是css中常见的inline,inline-block,block等,这些盒模型决定了DOM节点在屏幕上展示的位置和大小。

3

4.组织盒模型布局

将第三步解析出来的盒模型进行分块布局,如一个div块、一个section块等:

4

5.渲染展示

将上一步组织好的各个布局进行合成,最后展示在前端界面上,这样一个完整的静态页面就展示在用户面前。

通过上述浏览器渲染流程可以看出,为了解析渲染CSS样式,CSS引擎需要浏览器引擎出来出来的DOM树样式规则表。CSS引擎需要遍历完整的DOM树节点,并计算每一个节点的样式,就好比一个DOM节点就是一个表,表中的内容是该节点所计算出来的样式集合,如:

5

为了实现这一点,CSS引擎需要做到如下两点:

  • 找出CSS中对应的的规则的DOM节点,例如CSS中声明了.test { color: red },那么CSS引擎需要找出类名为test的节点,这个过程称为选择器匹配
  • 将父节点或者默认的样式值应用在未声明的节点上,如CSS中声明了默认样式body { color: red },那么body下的任意元素都会继承body的color值;又如CSS中声明了.test p { color: yellow },那么CSS选择器需要先找到类名为test的节点,然后再在该节点下找到p元素节点,再讲样式规则应用上去,这个过程称之为级联

选择器匹配

CSS引擎在进行选择器匹配的过程中,因为同一个元素可能匹配到多个样式声明,如:

.test { color: red; }
.test p { color: green; }

那CSS引擎会先将所匹配到的所有样式规则存放在一个结果表中,由于多个样式可能有重合,结果表中存在一个称为权重的标志,决定该元素最后采用哪种样式:

7

如上图,由于一个p元素最后匹配到的样式规则有四种,最后CSS引擎需要根据最后一列的权重值应用p元素的样式。

完成选择器匹配后,接下来就是应用级联将其余所有的节点应用上相应的样式。

级联

有了级联,CSS就变得更加容易,也变得更加容易维护。例如你在body声明了一个color样式,那么这个body下所有元素如果没有再重新赋予新的样式值的情况下都会使用body的这个color值。CSS引擎为了做到这一点,会先到计算好的样式表中检查这个节点是否有该默认的样式, 并一级一级的检查该节点的父节点上是否有该样式,如果有,则使用其祖先节点上的样式;如果没有,则使用默认样式。

样式共享

一个静态页面可能会很多很多的CSS样式,如果每个样式属性在被使用时都开辟一个内存空间,那么开销是非常大的,事实上,CSS引擎是以“样式共享”的形式引用各个样式属性的。CSS将同一类样式作为一个数据结构存放,在被使用到时,会以指针的形式引用,这样所有在页面上用到的CSS样式实际上都是公用同一个数据内存空间:

9

结尾

CSS引擎是浏览器引擎的一部分,通过CSS引擎,浏览器可以顺利的将CSS样式规则应用到各个DOM节点上,以达到我们所想要的各种样式效果,另本文只是本人对CSS引擎工作原理的简单理解,说的比较简单显浅,如果有误,欢迎提出。

(完)

参考:

Inside a super fast CSS engine: Quantum CSS (aka Stylo)


原创不易,如果觉得这篇文章对你有帮助,不如赏杯咖啡吧
微信
支付宝