1. 特殊性
对于每个规则,用户代理会计算选择器的特殊性,并将这个特殊性附加到规则中的各个声明。如果一个元素有两个或多个冲突的的属性声明,那么有最高特殊性的声明就会胜出。
选择器的特殊性由选择器本身的组件确定。特殊性表述为四个部分, 数字化为 0,0,0,0。
一个选择器的具体特殊性如下确定:
① 对于选择器中给定的各个 ID 属性值,加 0,1,0,0。
② 对于选择器中给定的各个类属性值、属性选择或伪类,加 0,0,1,0。
③ 对于选择器中给定的各个元素和伪元素,加 0,0,0,1。
④ 结合符合通配选择器对特殊性没有任何贡献。
⑤ 通配选择器对一个选择器的特殊性没有贡献,其特殊性为 0,0,0,0。
⑥ 内联样式的特殊性为 1,0,0,0。
有时某个声明十分重要,超过了其他所有声明,可以在声明结束分号之前插入 !important
来进行重要声明(注意 !important
的位置,错误的位置会使声明失效)。如果一个重要声明和一个非重要声明冲突,胜出的总是重要声明。
2. 继承
继承是一个元素向其后代元素传递属性值所采用的机制。
但是并不是所有的属性都能继承。一般的,大多数框模型属性(包括内边距、外边距、背景和边框)都不能继承。
继承没有特殊性,甚至连 0 特殊性都没有。
关于通配选择器的问题:由于通配选择器适用于所有元素,而且具有 0 特殊性,但是继承根本没有特殊性,所以会出现短路继承的效果,所以避免不加区别地使用通配选择器。
3. 层叠
确定应当向一个元素应用哪些值时,不仅仅要考虑继承,还要考虑声明的特殊性,另外需要考虑声明本身的来源。这个过程称之为层叠。
层叠的规则如下:
① 找出所有相关的规则,这些规则包含与一个给定元素匹配的选择器。
② 按照显示权重对应用到该元素的所有声明排序。标志 !important
的规则的权重要高于没有 !important
标志的规则。
按来源对应用到给定元素的所有声明排序。声明权重:读者的重要声明 > 创作人员的重要声明 > 创作人员的正常声明 > 读者的正常声明 > 用户代理声明。
③ 按特殊性对应用到给定元素的所有声明排序。有较高特殊性的元素权重要大于有较低特殊性的元素。
④ 按出现顺序对应用到给定元素的所有声明排序。一个声明在样式表或文档中越靠后先出现,它的权重越大。
PS:如果样式表中有导入的样式表,一般认为出现在导入样式表中的声明在前,主样式表中的所有声明在后。