#no-descending-specificity

禁止在具有较高优先级的选择器后出现被其覆盖的较低优先级的选择器。

    #container a { top: 10px; } a { top: 0; }
/** ↑                           ↑
 * 这些选择器的顺序代表了降序的优先级 */

源码顺序在 CSS 中很重要,当两个选择器具有相同优先级时,最后出现的选择器将具有优先权。然而,当选择器之一具有更高优先级时,情况是不同的。在这种情况下,源码顺序确实重要:具有更高优先级的选择器即使先出现也会胜出。

这两种优先级,源码顺序和优先级机制的冲突在阅读样式表时会引起一些混乱。如果具有更高优先级的选择器出现在它覆盖了的选择器之前,我们必然更加难以理解它,因为它违反了源码顺序期望。当覆盖选择器总是在它们要覆盖的选择器之后时,样式表是最清晰的。 这样,源码顺序和优先级这两种机制可以很好地协同工作。

该规则将尽可能强制执行。(它不能捕获每个实际的覆盖选择器(因为它不知道 DOM 结构),但是它可以捕获某些常见错误。)

它的工作原理是:此规则查看每个完整选择器中的最后一个复合选择器,然后将其与样式表中以相同方式结尾的其他选择器进行比较。

所以 .foo .bar(其最后一个复合选择器是 .bar)将与 .bar#baz .bar 比较,而不是与 #baz .foo.bar .foo

a > li#wag.pit(其最后一个复合选择器是 li#wag.pit)将与 div li#wag.pita > b > li + li#wag.pit 比较,而不是与 lili #wag 等。

另外还有一个重要特性:针对伪元素的选择器与没有伪元素的类似选择器被认为是不可比较的,因为它们定位了渲染页面上的不同元素。例如,a::before {} 将不会与 a:hover {} 进行比较,因为 a::before 以伪元素为目标,而 a:hover 则以实际的 <a> 为目标。

此规则仅比较同一媒体上下文中的规则。所以 a {} @media print { #baz a {} } 不违规。

此规则在计算选择器的优先级之前解析嵌套选择器。

#选项

#true

以下模式被视为违规:

b a {}
a {}
a + a {}
a {}
b > a[foo] {}
a[foo] {}
a {
  & > b {}
}
b {}
@media print {
  #c a {}
  a {}
}

以下模式被视为违规:

a {}
b a {}
a {}
a + a {}
a[foo] {}
b > a[foo] {}
b {}
a {
  & > b {}
}
a::before {}
a:hover::before {}
a {}
a:hover {}
@media print {
  a {}
  #c a {}
}
a {}
@media print {
  #baz a {}
}