CSS 选择器的权重(特异性)是确定在多个选择器应用于同一元素时,哪个选择器的样式会最终生效的关键因素。然而,关于 CSS 选择器特异性的理解,常常存在一些常见的误解。本文将探讨这些误解,并帮助大家理解 CSS 选择器的权重。
误解一:权重是一个数字
CSS 选择器的权重并不是一些数字。所以,计算元素的权重时,并不是简单的将权重数值相加就可以了。
CSS 选择器的权重由三个部分组成,表示为 (a, b, c),其中 a、b、c 分别代表了不同选择器类型的权重。具体规则如下:
- ID选择器:权重值为(1, 0, 0),通过元素的ID选择器来匹配的样式。
- 类选择器、属性选择器和伪类选择器:权重值为(0, 1, 0),类选择器(如.example)、属性选择器(如[type="text"])和伪类选择器(如:hover)具有相同的权重。
- 元素选择器和伪元素选择器:权重值为(0, 0, 1),元素选择器(如p)和伪元素选择器(如::before)具有相同的权重。
注意:通配符选择器(如 *)、子选择器(如 >)、相邻兄弟选择器(如 +)和兄弟选择器(如 ~)对权重没有贡献,即它们的权重为 (0,0,0)。
权重计算规则:
例如:
/* 权重为 (0,0,1) */
div { color: red; }
/* 权重为 (0,1,0) */
.class1 { color: green; }
/* 权重为(1,0,0) */
#id1 { color: blue; }
/* 权重为(1,1,0)(因为 ID 选择器的权重高于类选择器)*/
#id1.class1 { color: purple; }
/* 权重为(0,1,0),因为只有一个类选择器 */
.class1 { color: red; }
/* 权重为(0,1,0),即使有两个类选择器,但它们的权重不会相加 */
.class1.class2 { color: blue; }
/* 权重为(1,1,0),因为一个ID选择器和一个类选择器的组合 */
#id1.class1 { color: green; }
/* 权重为(0,1,0),因为有三个类选择器,但每个类选择器的权重仍然是(0,1,0) */
.class1.class2.class3 { color: purple; }
在上面的例子中,即使选择器中包含多个相同的组成部分(如类选择器),每个组成部分的权重仍然是独立的,并且不会累加。因此,在选择器冲突时,特异性更高的选择器将覆盖特异性较低的选择器。如果特异性相同,则后出现的规则会覆盖先出现的规则(即“后来者居上”的原则)。
详细来看看最后一个例子:
对于选择器 .class1.class2.class3,其特异性(权重)的计算方式如下:
- 该选择器包含三个类选择器(.class1、.class2 和 .class3)。
- 在CSS特异性计算中,每个类选择器都贡献(0,1,0)的特异性值。
- 由于特异性值不会跨类型累加,我们只需关注类选择器这一位(即第三位)上的数量。
- 在这个例子中,有三个类选择器,但每个类选择器在类选择器这一位上的值仍然是 1。
但是,这并不意味着三个类选择器加起来就是 3。实际上,在选择器的特异性计算中,我们不会将类选择器这一位上的值相加。我们只需记录存在多少个类选择器(在这个例子中是三个)。然而,在描述特异性时,我们通常(0,3,0)不直接写出这样的表示法,因为按照标准的特异性表示法,我们只需指出在类选择器这一位上有三个单位(即 0,1,0 出现了三次)。
但是,为了明确和避免混淆,当我们谈论这种由多个同类选择器组成的选择器的特异性时,我们可能会说它在类选择器这一位上的特异性“权重”相当于(0,3,0)(尽管这不是标准的表示法)。不过,在比较选择器的特异性时,我们只需记住它在类选择器这一位上有三个单位。
因此,.class1.class2.class3 的特异性(权重)按照标准的表示法是 (0,1,0)(但因为有三个类选择器,所以在类选择器这一位上的“等效权重”可以理解为三个单位)。
误解二:使用style属性会增加权重
很多人认为,在 HTML 元素上直接使用style属性来定义 CSS 样式会增加样式权重。
在 HTML 元素上直接使用style属性并不会增加元素的特异性。实际上,style 属性定义的样式具有最高的优先级,这通常被称为“内联样式”或“行内样式”。但这种高优先级并非来源于特异性的计算,而是源于CSS层叠和冲突解决机制中的一个特殊规则。
CSS层叠的优先级规则中,style属性(内联样式)的优先级高于其他任何在样式表中定义的样式规则,无论这些样式规则使用了何种选择器(ID、类、元素等)。但请注意,这种优先级与特异性是两个不同的概念。
- 特异性:用来确定哪些样式规则会应用到元素上的机制。特异性是一个由三个部分组成的权重值当两个或更多的样式规则都适用于同一个元素时,浏览器会根据这些规则的特异性来决定哪个规则会最终应用到该元素上。
- 优先级:在特异性相同的情况下,用来确定哪个样式规则会生效的机制。这时,会按照以下顺序来确定优先级,在优先级上,用户样式会覆盖用户代理样式,而作者样式会覆盖用户样式(除非用户样式使用了!important):
内联样式
作者的样式表
重要的作者样式
普通的作者样式
用户代理样式(User Agent Stylesheet):浏览器的默认样式,如默认字体大小、颜色等。
用户样式(User Styles):通过浏览器设置或扩展自定义的样式。
作者样式(Author Styles):在样式表中定义的样式。
在作者定义的样式中,内联样式具有最高的优先级,即使其他样式规则具有更高的特异性。但请注意,这并不意味着内联样式具有更高的特异性;它只是在优先级上高于其他样式。因此,style属性并不会增加元素的权重。
误解三:使用!important会增加权重
我们知道,在 CSS 中使用 !important 会使得样式的优先级最高。不过,在 CSS 声明中使用 !important 并不会增加其特异性。
特异性(权重)是一个由选择器类型决定的权重系统,用于确定在多个样式规则应用于同一元素时,哪个规则会被优先应用。而!important则是一个覆盖机制,用于改变声明的优先级,使其在CSS的层叠顺序中具有更高的权重。
当浏览器需要确定一个元素的最终样式时,它会按照以下步骤进行:
因此,!important并不改变特异性,而是在特异性比较之后,作为一个额外的优先级判断依据。使用!important应该谨慎,因为它会破坏CSS的层叠和特异性规则,使得样式更难于维护和调试。在可能的情况下,最好通过优化选择器和组织样式规则来避免使用!important。