CSS:not()选择器是否应该与远程后代一起使用?

aug*_*tin 6 css css-selectors css3

以下是CSS3 :not()伪类的官方文档:
http://www.w3.org/TR/css3-selectors/#negation
和CSS Selectors Level 4增强功能:http:
//dev.w3.org/csswg/selectors4 /#否定

我一直在寻找实现和浏览器支持:not(),但我发现的唯一例子是单个元素或元素的直接子元素,例如:

div *:not(p) { color: red; }
Run Code Online (Sandbox Code Playgroud)

上面的例子适用于<p>直接的孩子<div>,但是当它<p>是一个更遥远的后代时它不起作用<div>.

div :not(p) {
    color: red;
}
Run Code Online (Sandbox Code Playgroud)
<div>
    <ul>
        <li>This is red</li>
    </ul>
    <p>This is NOT</p>
    <blockquote><p>This is red but is not supposed to be!</p></blockquote>
</div>
Run Code Online (Sandbox Code Playgroud)

如果答案在上面的官方文档中,那么我没有找到/理解它.正如我所说的,我搜索了这个网站和网站,但找不到任何关于支持或缺乏的讨论:not()作为另一个元素的孙子.

这应该像我认为的那样工作吗?

Bol*_*ock 9

这应该像我认为的那样工作吗?

不,你看到的行为是正确的.

在你的最后一个例子中,虽然<blockquote>包含a <p>,但它<blockquote>本身就是匹配的*:not(p),以及它必须是它的后代的条件<div>.该样式仅应用于<blockquote>,但它由内部继承<p>.

该<p>元素本身仍然被反对否定,所以<p>本身仍然被排除在你的选择.它只是从其父<blockquote>元素元素继承文本颜色.

即使它的相对接近的祖先都没有与选择器相匹配,你也有类似的元素html并且body也要担心 - 尽管你可能只是body在开始时选择选择器:

body div...
Run Code Online (Sandbox Code Playgroud)

这就是为什么我经常强烈建议不要使用:not()选择器来过滤后代,特别是当没有使用类型选择器限定时(如div在你的例子中).它不像大多数人所期望的那样工作,并且使用继承的属性color只会使问题复杂化,而不会使作者更加困惑.有关更多示例,请参阅我对这些其他问题的回答:

所描述的问题的解决方案是简单地将不同的颜色应用于<p>元素.由于继承,您将无法使用选择器简单地排除它们:

/* Apply to div and let all its descendants inherit */
div {
  color: red;
}

/* Remove it from div p */
div p {
  color: black;
}
Run Code Online (Sandbox Code Playgroud)

选择器级别4:是的,:not()确实已经增强,可以接受包含组合器的完整复杂选择器.从本质上讲,这意味着(一旦浏览器开始实现它),您将能够编写以下选择器并使其完全符合您的要求:

p:not(div p) {
  color: red;
}
Run Code Online (Sandbox Code Playgroud)

如果有人有兴趣,这今天在jQuery中工作.

  • @augustin:或者,总而言之,`:not()`选择器就像任何其他伪类或类选择器或ID选择器一样. (2认同)