为什么这个CSS :not()声明不能向下过滤?

4

我希望选择不是特定类名“no”的后代的span元素。这是我的CSS:

div:not(.no) span{background-color:#00f;}

这是HTML代码。
<div>
    <span>yes 1</span>
</div>
<div class="no">
        <span>no 1</span>
</div>
<div class="no">
    <div>
           <span>no 2</span>
    </div>
</div>

两个问题:

  1. Why does my CSS apply to both yes 1 and no 2?
  2. Why does the whole thing break if I switch to a universal selector?

    *:not(.no) span{background-color:#00f;}
    

以下是JSFiddle中的代码:http://jsfiddle.net/stephaniehobson/JtNZm/


3个回答

8
  1. Both of the span elements' parent div elements don't have the class no, regardless of whether any other ancestors do have it or not:

    <div> <!-- This is div:not(.no), pretty much a given -->
        <span>yes 1</span>
    </div>
    
    <div class="no"> <!-- In this case, although this is div.no... -->
        <div>        <!-- ... this is div:not(.no)! -->
               <span>no 2</span>
        </div>
    </div>
    
  2. Both html and body, which are ancestors of your div and span elements, satisfy *:not(.no) when using a universal selector (or rather, when omitting a type selector). This causes all of your span elements to have the background color.

其中一种解决方案是使用子级组合器将您的否定过滤器锚定到 body 元素上,如果您的顶层 div 元素始终是 body 的子元素:

body > div:not(.no) span { background-color: #00f; }

jsFiddle 演示

另一种解决方法是直接使用覆盖样式。


这是 jQuery 优化问题的一小部分,我无法确定任何元素在 DOM 中彼此之间的关系。这有点像一个让我困扰的离题,但现在已经不是了 :) - Stephanie Hobson
+1。谢谢。我终于明白了我的问题是什么,这促使我询问相关问题https://dev59.com/M3rZa4cB1Zd3GeqP7M8K. - augustin

4
BoltClock是正确的。如果您将选择器表述为以下形式,可能会更有意义:
选择任何一个元素, 它是从一个
元素 下降的,其值不包含单词。
在您的示例中,每个选定的实际上都是从一个
下降的,其值不包含单词 - 第二个也从一个值包含单词的
下降,这并不否定(哈!)前面的陈述。
有趣的是,我敢打赌,如果您将第二个下移一级,则仍将匹配第二个。 CSS没有元素的接近概念,因此任何祖先
都应足以匹配选择器,无论它是否“更接近”

我试过了,你是对的,如果我将第二个“no”下移一级,第二个“span”仍然会被匹配。比有趣更令人沮丧 :P - Stephanie Hobson
2
天啊,是Eric Meyer! :D - BoltClock

0

我认为最好的选择是将您的语句分成两部分:

div span { background-color:#00f; }
.no span { background-color:#fff; }

您可以在这里查看效果:http://jsfiddle.net/JHTqp/


不幸的是,这只是一个更大的jQuery优化问题的一小部分,这只是我的测试案例。 - Stephanie Hobson

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