我很困惑为什么这个例子不起作用:
CSS:
p {
color: red;
}
div:not(.exclude) p {
color: green;
}
HTML:
<div>
<div class="exclude">
<p>I should be red</p>
</div>
<div>
<p>I should be green</p>
</div>
</div>
最终结果是<p>
都是绿色的,但我原本预计第一个是红色的。 Here's a JSFiddle.
有趣的是,我找到了三种不同的方法来实现它:
<div>
<div>
到另一个元素(例如<section>
)div
到第二个CSS选择器的开头div div:not(.exclude) p
)另一个奇怪的方法来打破它:
<div>
<section>
醇>
此选择器仅适用于一个元素;你不能用它来排除所有的祖先。例如,
body :not(table) a
仍将应用于表格内的链接,因为<tr>
将与选择器的:not()
部分匹配。
这是有道理的,但我认为这不会发生在这里。由于<div class="exclude">
与其直接子<p>
之间没有任何内容,因此无论嵌套内部是什么,它都应触发规则。我错过了什么?如果有人能帮助我理解这一点,我真的很感激。
答案 0 :(得分:6)
由于
<div class="exclude">
与其直接子<p>
之间没有任何内容,因此无论嵌套内部是什么,它都应该触发规则。我错过了什么?
<p>
是顶级<div>
和<div class="exclude">
的后代。因此,虽然后者与选择器不匹配,但前者确实如此,因此您有匹配。无法匹配选择器的祖先比那个选择器更接近<p>
并不重要。
解决方案1和2完全消除了这一匹配。
解决方案3在<div>
的祖先中不存在其他<p>
时有效,因为您将选择器限制为那些确切的条件,按照确切的顺序。这意味着如果您将class属性从内部<div>
交换到外部属性,它将不再与选择器匹配,相反,如果您从内部{{1>交换了类选择器对于外部的选择器,选择器将与原始HTML结构不匹配(同样,假设层次结构中不存在其他div
。)
在<div>
周围包裹另一个<div>
会导致选择器再次与<section>
匹配。忽略<div>
,与<section>
的方式大致相同。
另见:
答案 1 :(得分:4)
您的覆盖率<div>
甚至高于<div class="exclude">
。
在你的风格中,你已经指出 - 就:not
伪类而言 - 任何祖先<div>
都会这样做。 (即祖父母<div>
和父母<div>
一样好。)
要专注于直接父级,您的CSS需要使用直接子选择器(>
):
p {
color: red;
}
div:not(.exclude) > p {
color: green;
}
<div>
<div class="exclude">
<p>I should be red</p>
</div>
<div>
<p>I should be green</p>
</div>
</div>
答案 2 :(得分:1)
您在使用:not
时发现了一个常见的陷阱,其他答案也有所描述。 CSS中处理这个问题的经典方法,以及我们在CSS3之前做到这一点的方式为我们提供了用:not
射击自己的能力,就是编写几个规则,一个处理一般情况,第二个例外。在您的情况下,这看起来像:
p { color: red; }
div p { color: green; }
div.exclude p { color: red; }