:not 选择器正在更改等效选择器的计算顺序



我有一个问题,我在一个相当大的CSS代码库中工作,该代码库经常使用覆盖以前定义的类/选择器。因此,它对它们的定义顺序非常敏感。

这是我需要它如何工作的示例

.grid {
padding:25px;
background-color: red;
}
.grid {
padding:50px;
background-color: green;
}
<li>
<div class="grid">
Test
</div>
</li>

请注意第二个.grid定义如何覆盖第一个定义。

这就是现在正在发生的事情:

.grid:not(.ui) {
padding:25px;
background-color: red; 
}
.grid {
padding:50px;
background-color: green;
}
<li>
<div class="grid">
Test
</div>
</li>

使用伪类悬停:not会将评估的优先级移动到正常类定义之后。我需要以与以前相同的顺序对其进行评估,但我需要 :not 选择器。除了重构之外还有其他解决方案吗?

:not规则更具体,因此优先级更高。

如果你不能重构,你也可以在另一个规则上放置一个虚假的 :not 条件,这样它们将具有相同的优先级,从而恢复为文档顺序:

.grid:not(.ui) {
padding:25px;
background-color: red; 
}
.grid:not(.nonexistentclassname) {
padding:50px;
background-color: green;
}
<li>
<div class="grid">
Test
</div>
</li>

您只需要使要优先的选择器比另一个更具体。如果向元素添加一个"虚拟"类,则可以将该类添加到第二个选择器中以使其更具体(或者至少在最后一个选择器获胜的地方打成平局)。

CSS 特异性计算如下:

内联样式为 1000 分 选择器中id得 100 分 选择器中的类或伪类 10 分 选择器中的元素或伪元素为 1 分

在您的情况下:

.grid:not(.ui)

值 20 分,因为选择器中有 1 个类和一个伪类。

但:

.grid

只值10分,因为一个班级。

/* This selector is worth 20 points */
.grid:not(.ui) {
padding:25px;
background-color: red; 
}
/* This selector is also worth 20 points, but becomes it comes 
after the other one, the location breaks the tie. */
.grid.special {
padding:50px;
background-color: green;
}
<li>
<!-- Adding another "dummy" class to the element allows you
to correctly find it with your CSS, and do it with a more
specific selector, if needed. -->
<div class="grid special">
Test
</div>
</li>

而且,如果您需要(出于某种原因)颠倒选择器的顺序怎么办?只需将应该"获胜"的那个更具体一点:

/* This selector is worth 21 points */
div.grid.special {
padding:50px;
background-color: green;
}
/* This selector is worth 20 points */
.grid:not(.ui) {
padding:25px;
background-color: red; 
}
<li>
<!-- Adding another "dummy" class to the element allows you
to correctly find it with your CSS, and do it with a more
specific selector, if needed. -->
<div class="grid special">
Test
</div>
</li>

这是一个了解特异性计算方式的好网站,让您"玩"选择器。

在第一个示例中,.grid个选择器的特异性值分别为 10(类 = 10)。因此,由于两个规则具有相同的特异性,因此它们的源顺序决定。

在第二条规则中,.grid:not(.ui)的特异性值为 20(2 个类;:not()伪类没有特异性值)。源顺序是从属的,因为规则具有不同的特异性值。

因此,为了实现您的目标(与以前相同的行为,但:not()应用于第一条规则),您需要将第二条规则的特异性提高至少 10 倍。

一种方法是在第二条规则中添加无用的:not()。此方法在另一个答案中描述,并且是规范允许的:

6.6.7. 否定 伪类

注意:伪:not()允许编写无用的选择器。为 实例:not(*|*),它根本不表示任何元素,或者foo:not(bar),相当于foo但具有更高的 特 异性。

.grid:not(.ui) {
padding:25px;
background-color: red; 
}
.grid:not(.bar) {
padding:50px;
background-color: green;
}
<div class="grid">Test</div>

特异性计算器

最新更新