是CSS:not()选择器应该与遥远的后代工作吗? [英] Is the CSS :not() selector supposed to work with distant descendants?

查看:217
本文介绍了是CSS:not()选择器应该与遥远的后代工作吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下是CSS3的官方文档:not()pseudo selector:

http://www.w3.org/TR/css3-selectors/#negation

和建议的CSS4增强功能:

http://dev.w3.org/csswg/selectors4/#negation



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

  div:not(.exclude){} 
div *:not(p){color:red;}

上述第二个示例在< p> < div> 的直接子级,但是至少在我的浏览器中,< p> < div> 的更远的后代。



CSS:

  div#test:not(p){ 
color:red;
}

HTML:

 < div id =test> 
< ul>< li>这是红色< / li>< / ul&
< p>这不是< / p>
< blockquote>< p>这是红色的,但不应该是!< / p>< / blockquote>
< / div>

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



问题1:根据您对标准的理解,这是否应该像我认为的那样工作?



问题2:可以在浏览器中使用。无论是否,你能告诉哪个浏览器和哪个版本。 (我对Firefox,Konqueror&hellip特别感兴趣)

解决方案


问题1: / strong>根据你对标准的理解,这是否应该像我认为的那样工作?


不,它的工作正常根据标准。



在最后一个例子中,虽然< blockquote> 包含< p> ,它是匹配< blockquote> 本身*:not(p) code>,以及它必须是< div> 的后代,这是它的条件。该样式仅适用于< blockquote> ,但它随后被< p> / code>里面。



< p> 元素本身仍然取决于否定,因此< p> 本身仍然会从您的选择器中排除。它只是从它的父项,< blockquote> 元素继承文本颜色。



相对接近的祖先匹配选择器,你有像 html body 的元素也担心 - 虽然你可能只是在一开始就粘贴在 body 选择器:

  body div ... 

这就是为什么我经常推荐不要使用:not )选择器,用于过滤后代,特别是当没有使用类型选择器限定时(如示例中的 div )。它不工作的方式大多数人期望它,和使用继承的属性,如 color 只是用来弥补这种误解。有关更多示例,请参阅我对这些其他问题的解答:





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

  / *应用于div#test它的所有后代继承* / 
div#test {
color:red;
}

/ *从div中删除它#test p * /
div#test p {
color:black;
}




问题2:它在您的浏览器中工作。无论是否,你能告诉哪个浏览器和哪个版本。 (我对Firefox,Konqueror特别感兴趣...)


它应该符合每个浏览器的标准。 KHTML拥有错误,其中:not() selector接受了多个简单的选择器,但是这是早期修复,并且它与这个问题无关。



在选择器4 :yes,:not()确实已经增强以接受包含组合器的完全复杂选择器。基本上,这意味着(一旦浏览器开始实现它),你将能够编写以下选择器,并且它完全按照你想要的方式:

  p:not(div#test p){
color:red;
}

如果有人感兴趣,

Here is the official documentation for the CSS3 :not() pseudo selector:
http://www.w3.org/TR/css3-selectors/#negation
and the proposed CSS4 enhancement:
http://dev.w3.org/csswg/selectors4/#negation

I've been searching about the implementation and browser support for :not() but the only examples I found were with a single element or with a direct child of an element, e.g.:

div:not(.exclude) {}
div *:not(p) {color: red;}

The second example above works when <p> is a direct child of <div> but, with my browsers at least, it does not work when <p> is a more distant descendant of <div>.

CSS:

div#test :not(p) {
  color: red;
}

HTML:

<div id="test">
<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>

If the answer is in the official documentation above, then I didn't understand them. As I said, I have searched this site and the web but couldn't find any discussion about the support or lack thereof of :not() as grand-children of another element.

Question 1: According to your understanding of the standards, is this supposed to work like I think it should?

Question 2: Does it work in your browser. Whether it does or not, can you tell which browser and which version. (I am especially interested in Firefox, Konqueror…)

解决方案

Question 1: According to your understanding of the standards, is this supposed to work like I think it should?

No, it's working correctly according to the standards.

In your last example, although the <blockquote> contains a <p>, it's the <blockquote> itself that's matching *:not(p), as well as the condition that it must be a descendant of the <div>, which it is. The style is applied only to the <blockquote>, but it is then inherited by the <p> inside it.

The <p> element itself still counts against the negation, so the <p> itself is still being excluded from your selector. It's just inheriting the text color from its parent, the <blockquote> element.

Even if none of its relatively close ancestors matched the selector, you have elements like html and body to worry about as well — although you could probably just tack on a body selector in the very beginning:

body div...

This is why I often recommend against using the :not() selector for filtering descendants, especially when not qualified with a type selector (like div in your example). It doesn't work the way most people expect it to, and the use of inherited properties like color only serves to compound this misunderstanding. See my answers to these other questions for more examples:

The solution to the problem described is to simply apply a different color to <p> elements. You won't be able to simply exclude them with a selector because of inheritance:

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

/* Remove it from div#test p */
div#test p {
  color: black;
}

Question 2: Does it work in your browser. Whether it does or not, can you tell which browser and which version. (I am especially interested in Firefox, Konqueror…)

It should behave according to the standards in every browser. KHTML had a bug where its :not() selector accepted more than one simple selector, but that was fixed early on, and it isn't related to this issue anyway.

On Selectors 4: yes, :not() has indeed been enhanced to accept full complex selectors that contain combinators. Essentially, this means (once browsers begin implementing it) you will be able to write the following selector and have it do exactly what you want:

p:not(div#test p) {
  color: red;
}

In case anyone is interested, this works in jQuery today.

这篇关于是CSS:not()选择器应该与遥远的后代工作吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆