我怎样才能用很多否定 (:not) 覆盖选择器?

How can I override a selector with many negations (:not)?

例如,要设置标准输入的样式,我会这样写:

input:not([type="checkbox"]):not([type="radio"]) {
    background-color: blue;
}

然而,这会大大增加特异性,所以如果我想使用 class 覆盖它,我必须做类似的事情:

.red.red.red {
    background-color: red;
}

有没有办法在不改变功能的情况下降低原始输入选择器的特异性?

这可能会让您解决特异性问题:

input:not([type="checkbox"]):not([type="radio"]):not(.red)) {
    background-color: blue;
}

.red {
  background-color: red;
}
<input type="checkbox"><br>
<input type="radio"><br>
<input class="red">

不幸的是,在 Selectors 3 中,这是您所能做的最好的选择,因为 :not() 只接受一个简单的选择器。话虽如此,您的覆盖规则中的选择器可以替换为 input.red.red — 您不需要比属性选择器更多的 class 选择器,除非该规则必须出现在样式表的前面。

这是 Selectors 4 通过增强 :not() 解决的另一个问题:特异性。在 Selectors 4 中,您将能够用一个 :not() pseudo 替换所有这些否定,从而有效地将其在原始选择器中的特异性降低为仅一个属性选择器。来自 section 16:

The specificity of a :not() pseudo-class is replaced by the specificity of the most specific complex selector in its selector list argument.

由于任何属性选择器对 class 选择器都是同等特定的,因此列表中任意数量的单独属性选择器的特定性永远不会超过其中一个的特定性。这使您无需重复使用一个 class 选择器即可覆盖。

以下作为概念验证:

/* 1 type, 2 attributes -> specificity = (0, 2, 1)
input:not([type="checkbox"]):not([type="radio"]),
   1 type, 1 attribute  -> specificity = (0, 1, 1) */
input:not([type="checkbox"], [type="radio"]) {
    background-color: blue;
}

/* 1 type, 1 class      -> specificity = (0, 1, 1) */
input.red {
    background-color: red;
}
<input type="checkbox">
<input type="radio">
<input type="text">
<input class="red" type="text">