逗号分隔列表的特异性规则

Specificity rules for comma delineated lists

在使用级联样式表时,我观察到如下特定顺序:

第一定律:In-line 风格
第二定律:ID选择器的数量
第三定律:Class 个选择器的数量
第四定律:元素选择器的数量

因此,具有 in-line 样式的项目排在第一位,然后是具有一个或多个 ID 选择器的声明,然后是具有一个或多个 class 选择器的声明,然后是具有一个或多个元素的声明选择器。 ID 越多,classes 和元素分别意味着更高的优先级。

从这个角度来看,我无法理解逗号分隔 ID、classes 或元素列表的位置。逗号分隔的列表是否有任何特殊的优先级规则?此外,在单个逗号分隔的列表中,ID、classes 和元素是否被视为单独的项目,用于计算特异性?

代码示例:

html, body, header {
  position: absolute;
  top: 0px;
}
header {
  position: relative;
  top: 50px;
}

在上面的例子中什么优先?逗号分隔的列表是否被视为引用单个元素,在这种情况下,header 仅因为级联中的最后一个元素而优先,或者逗号分隔的列表是否被视为多个元素,因此具有优先权?还是我应该首先考虑其他规则?

请记住,CSS 是层叠的 - 这意味着在 CSS 文件中进一步引用的样式将优先考虑选择器相同:

header {
  background-color: red;
}
p, span, header {
  background-color: yellow;
}
<header>
  HEADER
</header>

如果我们切换上面的声明,则会发生相反的情况:

p, span, header {
  background-color: yellow;
}
header {
  background-color: red;
}
<header>
  HEADER
</header>

如您所见,逗号分隔的选择器/声明没有区别 - 它们的处理方式与您单独选择它们时的处理方式相同。

在 CSS 中,用 , 分隔规则意味着列出多个选择器。因此 html, body, header 样式将应用于每个 htmlbodyheader,无论是否缺少某些样式。它不会为选择器提供任何优先级。

在您的示例中,header 位置将是绝对位置,因为第一条规则的优先级低于第二条规则。相同于:

header {
    position: relative;
}

header {
    position: absolute;
}

在这种情况下,它们都是元素选择器,因此输出的 css 将是底部的一个,因为 css 是从上到下呈现的优先级,在这种情况下采用最后一个元素。

Does a comma delineated list have any special precedence rules?

严格来说,一个selector-list没有自己的specificity值,但是为了级联的目的,一个selector-list的specificity等于匹配该元素的最具体的selector的specificity。这在 the current specification, but it appears in selectors-4 中没有明确说明。即便如此,由于选择器列表只不过是一种将两个或多个选择器组合在一个表达式中而无需重复它们的样式声明的方法,所以它以这种方式工作是有道理的。

请记住,选择器仅在与元素匹配时才与元素相关——否则,它永远不会进入特异性计算或级联的任何部分。

Also, in a single comma delineated list, are IDs, classes and elements considered separate items, for the purposes of calculating specificity?

每个简单选择器都有自己的特异性值,但这些值在复杂选择器级别相加。复杂选择器是选择器列表的一部分。例如,选择器列表

.foo > .bar, nav input:checked + label

有两个复杂的选择器:

  1. .foo > .bar,特异性为 (0, 2, 0)
  2. nav input:checked + label,特异性为 (0, 1, 3)

What takes precedence in the above example? Is the comma delineated list treated as referencing a single element, in which case the header would take precedence simply for being last in the cascade, or is the comma delineated list treated as multiple elements, and therefore takes precedence?

在您的示例中,选择器列表 html, body, header 由三个独立的单独类型选择器组成。由于每个元素一次只能是一种元素类型,因此很容易推断出列表中的所有三个选择器都是互斥的,即一个元素一次只能匹配三个选择器中的任何一个(或 none)。 header 元素永远无法匹配 htmlbody 选择器,因此这些选择器都不相关。您只需要处理 header 选择器,在您的示例中,特异性就不再是一个问题。结果是您的 second 规则(只有 header 选择器)优先,因为只有两个相关的选择器是同样具体的。

但是当您有一个选择器列表由多个可以匹配同一元素的选择器组成时,这就变得更切题了。假设上面示例中的两个选择器都可以匹配相同的 label 元素。所以我们有两个特异性选择器 (0, 2, 0) 和 (0, 1, 3) 都匹配相同的元素。正如在我的回答的第一段中,特异性等于最具体的选择器 (0, 2, 0) 的特异性。它是 而不是 ,正如人们可能已经猜到的那样,所有 匹配选择器 (0, 3, 3) 的总特异性,或者最不具体(无论如何都没有意义)。

这意味着,例如,具有特异性为 (0, 3, 0) 的选择器的单独规则仍将优先于选择器列表,即使该列表中的两个选择器匹配相同的元素。考虑这个人为的例子(你 很少 在野外找到这样的例子):

.foo > .bar.baz {
  color: red;
}

.foo > .bar, nav input:checked + label {
  color: blue;
}
<nav class="foo">
  <input type="checkbox" id="check" checked>
  <label for="check" class="bar baz">Checkbox</label>
</nav>

请注意,无论复选框是否被选中,label never 变为蓝色。这是因为 .foo > .bar.baz 具有 (0, 3, 0) 的特异性,它高于上面给出的两个单独特异性中的每一个,即使它低于组合特异性,因为特异性永远不会以这种方式组合。