如何用许多否定(:not)覆盖选择器?

Posted

技术标签:

【中文标题】如何用许多否定(:not)覆盖选择器?【英文标题】:How can I override a selector with many negations (:not)? 【发布时间】:2017-07-29 14:40:47 【问题描述】:

例如,为了设置标准输入的样式,我编写如下内容:

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

但是,这大大增加了特异性,所以如果我想使用一个类来覆盖它,我必须执行以下操作:

.red.red.red 
    background-color: red;

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

【问题讨论】:

您始终可以使用!important 来覆盖特异性。 specificity.keegan.st 使用它来找到正确的选择器 @MichaelCoker 是的,但是这破坏了特异性。我尽量保持低特异性,对我来说使用.red.red.red 是比!important 更好的解决方案。 【参考方案1】:

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

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

:not() 伪类的特殊性被其选择器列表参数中最具体的复杂选择器的特殊性所取代。

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

以下works in 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">

【讨论】:

【参考方案2】:

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

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

【讨论】:

很有创意,我会给你:D。不幸的是,它不是很实用,因为您希望 .red 仍然继承原始样式但能够覆盖原始样式。抱歉,我的示例没有显示这一点。 是的,我不知道所有细节,所以我提出了一个概念。我知道这是一个远射。 谢谢,感谢您的努力! L4 :not() is 旨在解决特异性问题。看看我的回答。 (老实说I bugged joshhunt into posting this question,因为我们昨天还在聊天中讨论过......) 看看我不知道的整个世界。现在我可以看到我的答案是多么令人难以置信的断章取义;-) @BoltClock

以上是关于如何用许多否定(:not)覆盖选择器?的主要内容,如果未能解决你的问题,请参考以下文章

CSS基础

如何用CSS选择器查询和风格化Web元素

如何用核心数据填充选择器控制器

Verilog 如何用持续赋值语句实现2选1多路选择器

否定伪类

如何用 Jest 单元测试覆盖 TypeORM @Column 装饰器?