CSS 否定伪类: not()用于父元素/祖先元素

这快把我逼疯了:

HTML:

<div><h1>Hello World!</h1></div>

CSS:

*:not(div) h1 { color: #900; }

这不是写着“选择所有具有非 div元素的祖先的 h1元素... ?”因此,“你好,世界!”不应该是红色的,但它仍然是。

对于上面的标记,添加子组合符可以起作用:

*:not(div) > h1 { color: #900; }

但是,如果 h1元素不是 div元素的子元素,则它不会受到影响。例如:

<div><article><h1>Hello World!</h1></article></div>

这就是为什么我希望将 h1元素表示为 div元素的子元素,而不是子元素。有人吗?

52837 次浏览

Doesn't this read, "Select all h1 elements that have an ancestor that is not a div element...?"

It does. But in a typical HTML document, every h1 has at least two ancestors that are not div elements — and those ancestors are none other than body and html.

This is the problem with trying to filter ancestors using :not(): it just doesn't work reliably, especially when the :not() is not being qualified by some other selector such as a type selector or a class selector, e.g. .foo:not(div). You'll have a much easier time simply applying styles to all h1 elements and overriding them with div h1.

In Selectors 4, :not() has been enhanced to accept full complex selectors containing combinators, including the descendant combinator. Whether this will be implemented in the fast profile (and thus CSS) remains to be tested and confirmed, but once it is implemented, then you will be able to use it to exclude elements with certain ancestors. Due to how selectors work, the negation has to be done on the element itself and not the ancestor in order to work reliably, and therefore the syntax will look a little different:

h1:not(div h1) { color: #900; }

Anyone who's familiar with jQuery will quickly point out that this selector works in jQuery today. This is one of a number of disparities between Selector 3's :not() and jQuery's :not(), which Selectors 4 seeks to rectify.

The <html> element is not a <div>. The <body> element is not a <div>.

So the condition "has an ancestor that is not a <div>" will be true for all elements.

Unless you can use the > (child) selector, I don't think you can do what you're trying to do - it doesn't really make sense. In your second example, <article> is not a div, so that matches *:not(div) too.