当html加载完之后开始进行解析最终生成DOM树,然后与此同时相关的CSS解析器开始对文档中的样式表进行解析以便于生成CSSOM树。然后最终将DOM树和CSSOM树合并成render树在经过布局和绘制等过程最终绘制到浏览器窗口或者其他设备的显示屏上。那么在CSS解析器在解析样式表的过程中属性最终值是怎么确定的?
确定某个属性的值大致要经过这么几个过程:
首先通过从多条匹配规则中根据规则指定一个值(指定值),然后处理这个值称为一个能够继承的 计算值。再然后将那些通过必须通过其他的过程 比如布局 得到的值确定下来(确定值)。最后根据不同的载体对值进行合法的看处理,形成实际值。
如何确定指定值?
在这一阶段,一个节点上的同一个属性可能在多个样式表中都有声明,所以存在着冲突,为了解决这个冲突,在这一阶段将执行一系列的过程。整体上来说用户代理必须先根据下列机制(按优先顺序)给每个属性赋值一个指定值:
(1)如果层叠产生了一个值,就使用它。对于层叠规则将在接下来介绍。
(2)否则,如果属性是继承的并且元素不是文档树的根,使用其父元素的计算值
(3)否则使用属性的初始值,每个属性的初始值都在属性定义中指出了
如下图所示:
在第一部分中:
1根据重要性(常规或者重要)以及来源(编写者,用户或者用户代理)排序,升序优先级为:
用户代理声明
用户常规声明
编写者常规声明
编写者重要声明
用户重要声明
2相同重要性和来源的规则根据选择器的特殊性排序:更特殊的选择器将重写一般的。伪元素和伪类被分别算作常规元素和类
一般来说,浏览器会计算选择器的特殊性,讲声明块解组后,讲特殊性附加到每一个声明中去。特殊性的值规则如下:
一般是a b c d排列
a:代表形内样式
b:代表ID属性选择器的个数
C:代表各个类属性选择器或者属性选择器或者伪类选择器的个数
d:代表各个元素或者元素选择器的个数
其中通配符(*)有特殊性只不过不为abcd提供任何值所以为0000,但是结合符没有任何的特殊性。
3最后,根据指定顺序排序:如果两个声明的权重,来源和特殊性都相同,后指定的生效。引入的样式表中的声明被认为在样式表本身的所有声明之前
在继承这一部分中
继承而来的样式是没有特殊性或者重要性的,一般情况下继承父元素的属性的值是计算后的值,但是也存在着例外。
什么是计算值,确定值,实际值?
计算值就是将指定值的结果中那些相对的内容进行绝对处理。比如URI如果为相对的地址,那么在这一过程中就是转化为绝对的地址,比如低于em,ex这些相对的单位,在这个过程中也会转化为绝对的数值。
确定值是处理那些需要经过布局这一过程孩子后才能确定大小的属性,比如如果子元素声明为百分数但是父元素的宽度必须到布局的时候才能确定。
实际值是根据文档显示的载体,确定最终的属性值,比如在浏览器pc端最后总显示是以像素为单位进行显示的,所以对于那些有小数的值会做近似的处理。