特异性

CSS 播客 - 003:明确性

假设您正在使用以下 HTML 和 CSS:

<button class="branding">Hello, Specificity!</button>
button {
  color: red;
}

.branding {
  color: blue;
}

这里有两条相互竞争的规则。 其中一个将按钮设置为红色,另一个将按钮设置为蓝色。 系统会对元素应用哪种规则? 了解 CSS 规范中关于特异性的算法 是了解 CSS 如何在竞争规则之间做出决定的关键。

特异性是级联的四个不同阶段之一, 在上一单元(级联级联)中介绍过。

特异性评分

每条选择器规则都会获得一个评分。 您可以将特异性视为总分,每个选择器类型都会根据该分数获得对应的分数。 得分最高的选择器将胜出。

根据具体的实际项目 权衡方法是确保您希望应用的 CSS 规则真正应用。 同时通常保持较低的分数以避免复杂程度。 得分应该只高到我们需要的水平 而不是追求最高得分。 将来,可能需要应用一些真正重要的 CSS。 如果想获得最高分,那么难度会很大。

对每种选择器类型进行评分

每种选择器类型都会获得积分。 将所有这些点相加即可计算选择器的总体特异性。

通用选择器

一个通用选择器 (*) 没有特定特征,因此获得了 0 分 也就是说,任何具有 1 分或更多分值的规则都会覆盖该规则

* {
  color: red;
}

元素或伪元素选择器

element(类型) 或伪元素 具有 1 个特异性点

类型选择器

div {
  color: red;
}

伪元素选择器

::selection {
  color: red;
}

类、伪类或属性选择器

伪类属性选择器获得 10 个特异性

类选择器

.my-class {
  color: red;
}

伪类选择器

:hover {
  color: red;
}

属性选择器

[href='#'] {
  color: red;
}

:not() 伪类本身并不会为特异性计算添加任何内容。 不过,作为实参传入的选择器会添加到特异性计算中。

div:not(.my-class) {
  color: red;
}

此示例将具有 11 个特异性 因为它有一个类型选择器 (div) 和一个在 :not()的类。

ID 选择器

ID 获得 100 个特异性点, 只要您使用 ID 选择器 (#myID) 而不是属性选择器 ([id="myID"])。

#myID {
  color: red;
}

内嵌样式属性

直接应用于 HTML 元素的 style 属性的 CSS, 会获得特异性得分 1000 分。 也就是说,要在 CSS 中替换它, 因此必须编写特别具体的选择器

<div style="color: red"></div>

!important 规则

最后,CSS 值末尾的 !important 将获得特异性分数 10,000 分。 这是单个商品可以获得的最高特异性。

!important 规则会应用于 CSS 属性, 因此整体规则(选择器和属性)中的所有内容不会获得相同的特异性分数。

.my-class {
  color: red !important; /* 10,000 points */
  background: white; /* 10 points */
}

检查您的理解情况

测试您对特异性评分知识的掌握情况

a[href="#"] 的特异性分数是多少?

1
a 的价值为 1 点,而 [href="#"] 的价值为 10 点。
5
再试一次!
11
a 分 1 分,[href="#"] 分 10 分,总分 11 分

具体情境

每个与元素匹配的选择器的特异性相加在一起。 请参考以下示例 HTML:

<a class="my-class another-class" href="#">A link</a>

此链接包含两类。 添加以下 CSS,该 CSS 将获得 1 个特异性点

a {
  color: red;
}

引用此规则中的一个类: 它现在具有 11 个特异性

a.my-class {
  color: green;
}

将另一个类添加到选择器中。 它现在具有 21 个特异性

a.my-class.another-class {
  color: rebeccapurple;
}

为选择器添加 href 属性, 它现在具有 31 个特异性

a.my-class.another-class[href] {
  color: goldenrod;
}

最后,向所有这些对象添加 :hover 伪类, 该选择器最终获得 41 个特异性

a.my-class.another-class[href]:hover {
  color: lightgrey;
}

检查您的理解情况

测试您对特异性评分知识的掌握情况

以下哪个选择器的价值是 21 分

article > section
元素的价值为 1 分,选择器中有 2 个元素,价值为 2 分
article.card.dark
元素得分为 1 分,类别得分为 10 分,再加上 2 个类和 1 个元素,因此此选择器的价值为 21 分
article:hover a[href]
元素对应 1 个点,伪类和属性对应 10 个点,元素对应 2 个点,属性和类对应 20 个点,使得此选择器值 22 点

直观呈现特异性

在图表和特异性计算器中 具体程度通常如下所示:

展示从最具体到最不具体的选择器的示意图

左侧组是 id 选择器。 第二组是类、属性和伪类选择器。 最后一组是元素选择器和伪元素选择器。

以下选择器为 0-4-1,供您参考:

a.my-class.another-class[href]:hover {
  color: lightgrey;
}

检查您的理解情况

测试您对特异性可视化知识的掌握情况

以下哪个选择器是 1-2-1

section#specialty.dark
此选择器直观呈现为 1-1-1
#specialty:hover li.dark
🎉
[data-state-rad].dark#specialty:hover
此选择器直观呈现为 1-3-0
li#specialty section.dark
此选择器直观呈现为 1-1-2

切实提高特异性

假设我们有一些如下所示的 CSS:

.my-button {
  background: blue;
}

button[onclick] {
  background: grey;
}

使用如下所示的 HTML:

<button class="my-button" onclick="alert('hello')">Click me</button>

该按钮采用灰色背景 因为第二个选择器可获得 11 个特异性点 (0-1-1)。 这是因为它有一个类型选择器 (button), ,即 1 分;以及一个属性选择器 ([onclick]),即 10 分

上一条规则 (.my-button) 得 10 分 (0-1-0), 因为它有一个类选择器。

如果您想进一步完善此规则 重复类选择器,如下所示:

.my-button.my-button {
  background: blue;
}

button[onclick] {
  background: grey;
}

现在,该按钮将具有蓝色背景 因为新选择器获得了特异性分数 20 分 (0-2-0)。

如果有匹配的特异性分数,则最新的实例胜出

我们先继续使用按钮示例,并将 CSS 切换为以下代码:

.my-button {
  background: blue;
}

[onclick] {
  background: grey;
}

该按钮采用灰色背景 因为两个选择器具有相同的特异性分数 (0-1-0)。

如果按来源顺序切换规则 该按钮就会变为蓝色

[onclick] {
  background: grey;
}

.my-button {
  background: blue;
}

这是唯一一个较新的 CSS 胜出的情况。 为此,它必须与针对同一元素的另一个选择器的特异性相匹配。

资源