2

在实际的工作中,我们可能还有些疑惑,当有多个选择器作用在一个元素上时,哪个规则最终会应用到元素上?其实这是通过层叠机制来控制的,这也和样式继承(元素从其父元素那里获得属性值)有关。

层叠

CSS 是 Cascading Style Sheets 的缩写,这暗示 层叠(cascade) 的概念是很重要的。在最基本的层面上,它表明CSS规则的顺序很重要,但它比那更复杂。什么选择器在层叠中胜出取决于三个因素(这些都是按重量级顺序排列的——前面的的一种会否决后一种):

  • 重要性(Importance)
  • 特殊性(Specificity)
  • 源代码次序(Source order)

重要性

!important

在CSS中,有一个特别的语法可以让一条规则总是优先于其他规则:!important。把它加在属性值的后面可以使这条声明有无比强大的力量。

注意: 重载这个 !important 声明的唯一方法是在后面的源码或者是一个拥有更高特殊性的源码中包含相同的 !important 特性的声明。

知道 !important存在是很有用的,这样当你在别人的代码中遇到它时,你就知道它是什么了。但是!我们建议你千万不要使用它,除非你绝对必须使用它。您可能不得不使用它的一种情况是,当您在CMS中工作时,您不能编辑核心的CSS模块,并且您确实想要重写一种不能以其他方式覆盖的样式。 但是,如果你能避免的话,不要使用它。由于 !important 改变了层叠正常工作的方式,因此调试CSS问题,尤其是在大型样式表中,会变得非常困难。

样式表来源

要注意一个CSS声明的重要性取决于它被指定在什么样式表内——用户可以设置自定义样式表覆盖开发商的样式,例如用户可能有视力障碍,想设置字体大小对所有网页的访问是双倍的正常大小,以便更容易阅读。

相互冲突的声明将按以下顺序适用,后一种将覆盖先前的声明

  • 在用户代理样式表的声明 (例如:浏览器在没有其他声明的默认样式).
  • 用户样式表中的普通声明(由用户设置的自定义样式)。
  • 作者样式表中的普通声明(这是我们设置的样式,Web开发人员)。
  • 作者样式表中的重要声明
  • 用户样式表中的重要声明(优先级最高)

Web开发者的样式表覆盖用户的样式表是合理的,所以设计可以保持预期,但是有时候用户有很好的理由来重写web开发人员样式,如上所述,这可以通过在用户的规则中使用 !important

特殊性

特殊性基本上是衡量选择器的具体程度的一种方法——它能匹配多少元素。如上面所示的示例所示,元素选择器具有很低的特殊性。类选择器具有更高特殊性,所以将战胜元素选择器。ID选择器有甚至更高的专用性, 所以将战胜类选择器。

一个选择器具有的专用性的量是用四种不同的值(或组件)来衡量的,它们可以被认为是千位,百位,十位和个位——在四个列中的四个简单数字:

  • 千位:如果声明是在 style 属性中该列加1分(这样的声明没有选择器,所以它们的专用性总是1000。)否则为0。
  • 百位:在整个选择器中每包含一个 ID选择器就 在该列中加1分。
  • 十位:在整个选择器中每包含一个 类选择器属性选择器、或者 伪类 就在该列中加1分。
  • 个位:在整个选择器中每包含一个 元素选择器伪元素 就在该列中加1分。
注意: 通用选择器 (*), 复合选择器 (+, >, ~, ' ') 和否定伪类 (:not) 在专用性中无影响。

示例

选择器 千位 百位 十位 个位 合计值
h1 0 0 0 1 0001
#important 0 1 0 0 0100
h1 + p::first-letter 0 0 0 3 0003
li > a[href*="zh-CN"] > .inline-warning 0 0 2 2 0022
#important div > div > a:hover, 在一个元素的 <style> 属性里 1 1 1 3 1113
注意: 如果多个选择器具有相同的重要性和专用性,则选择哪一个选择器取决于 Source order(源代码次序)。

源代码次序(Source order)

如果多个相互竞争的选择器具有相同的重要性和专用性,那么第三个因素将帮助决定哪一个规则获胜——后面的规则将战胜先前的规则。

继承

CSS继承是我们需要研究的最后一部分,以获取所有信息并了解什么样式应用于元素。其思想是,应用于某个元素的一些属性值将由该元素的子元素继承,而有些则不会。

哪些属性默认被继承哪些不被继承大部分符合常识。如果你想确定,你可以 参考CSS参考资料—— 每个单独的属性页都会从一个汇总表开始,其中包含有关该元素的各种详细信息,包括是否被继承。

继承属性是CSS最基本的内容之一,一般不会特别考虑,但是还是要记住的是:

  • 大部分框模型属性(如border)不会继承。
  • 继承没有特殊性,且低于0,0,0,0 如 * {color: red;}

控制继承

CSS为处理继承提供了三种特殊的通用属性值:

  • inherit: 该值将应用到选定元素的属性值设置为与其父元素一样。
  • initial :该值将应用到选定元素的属性值设置为与浏览器默认样式表中该元素设置的值一样。如果浏览器默认样式表中没有设置值,并且该属性是自然继承的,那么该属性值就被设置为 inherit
  • unset :该值将属性重置为其自然值,即如果属性是自然继承的,那么它就表现得像 inherit,否则就是表现得像 initial

总结

层叠样式表这个名字很贴切。 CSS所采用的方法就是让样式层叠在一起,这是通过结合继承和特殊性做到的•。CSS2.1 的层叠规则相当简单。

  1. 找出所有相关的规则,这些规则都包含与一个给定元素匹配的选择器。
  2. 按显式权重对应用到该元素的所有声明排序。标志 !important 的规则的权重要高于没有 !important 标志的规则。按来源对应用到给定元素的所有声明排序。共有3种来源:创作人员、读者和用户代理。正常情况下,创作人员的样式要胜过读者的样式。有 !important 标志的读者样式要强于所有其他样式,这包括有 !important 标志的创作人员样式。创作人员样式和读者样式都比用户代理的默认样式要强。
  3. 按特殊性对应用到给定元素的所有声明排序,有较高特殊性的元素权重大于有较低特殊性的元素.
  4. 按出现的序对应用到给定元素的所和声明排序。一个声明在样式表或文档中越后出现,它的权重越大,如果样式表中有导入的样式表,一般认为出现在导入样式表中的声明在前,主样式表中的所有声明在后。

参考


Pines_Cheng
6.5k 声望1.2k 粉丝

不挑食的程序员,关注前端四化建设。