如何使用多个否定选择器(:not)来覆盖一个选择器?

6
例如,如果要为标准输入样式编写代码,可以像这样写:

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

然而,这样会大大增加特异性,所以如果我想使用类来覆盖它,我必须这样做:

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

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

您可以始终使用!important来覆盖特定性。 - Michael Coker
使用 https://specificity.keegan.st/ 来找到正确的选择器。 - DaniP
3
@MichaelCoker 是的,但那会降低特定性。我尽量保持特定性尽可能低,对我来说使用.red.red.red比使用!important更好。 - joshhunt
2个回答

4

很遗憾,在选择器 3 中,这是你能做的最好的事情,因为 :not() 只接受一个简单选择器。话虽如此,你覆盖规则中的选择器可以被替换为 input.red.red — 除非该规则必须出现在样式表中的早期位置,否则你不需要更多类选择器而是属性选择器。

选择器 4 解决的另一个问题就是增强了 :not() 的特异性。在选择器 4 中,你将能够用一个 :not() 伪类来代替所有这些否定选择器,从而有效地降低其在原始选择器中的特异性为仅一个属性选择器。根据 第16节

:not() 伪类的特异性由其选择器列表参数中最具体的复合选择器的特异性替代。

由于任何属性选择器与类选择器同样具体,因此在列表中有任意数量的孤立属性选择器的特异性永远不会超过它们中的一个。这使得你可以只使用一个类选择器进行覆盖而无需重复它。

以下 在 Safari 中起到了概念验证

/* 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">


1

这可能会解决你的特异性问题:

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">


1
这确实很有创意:D。不幸的是,它不太实用,因为您希望.red仍然继承原始样式,但具有覆盖原始样式的能力。我的示例没有显示这一点,抱歉。 - joshhunt
1
是的,我并不知道所有的细节,所以只是提出了一个概念。我知道这很冒险。 - Michael Benjamin
等等…他们什么时候取消了这个限制?我毫不知情。所以,:not([type="radio"]:not(.red)) 有效的。这可真有意思… - BoltClock
2
L4:not()被设计来解决特异性问题。请查看我的答案。(说实话,我在昨天的聊天中向joshhunt提出了这个问题...) - BoltClock
2
看看那个我之前不知道的整个世界。现在我可以看到我的回答是多么超出了上下文哈哈@BoltClock - Michael Benjamin
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接