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

109
这让我抓狂: HTML:
<div><h1>Hello World!</h1></div>

CSS:

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

这不是说“选择所有祖先不是 div 元素的 h1 元素”吗?因此,“Hello World!”不应该被着色为红色,但它仍然被着色了。

对于上面的标记,加入子组合器可以解决:

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

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

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

因此,我想将h1元素指示为div元素的后代而不是子元素。有人能帮忙吗?


7
顺便提一下,当你使用其他类型的选择器时,你可以直接省略 *,例如 :not(div),就像你指定 .class#id 一样,不需要使用 * - BoltClock
2个回答

130
这里是需要翻译的内容:

这不是说“选择所有具有非 div 祖先元素的 h1 元素吗?”

没错。但在典型的 HTML 文档中,每个 h1 至少有两个非 div 元素作为其祖先元素 —— 而这些祖先元素正是 bodyhtml

这就是使用 :not() 尝试过滤祖先元素时会遇到的问题:它不能可靠地工作,特别是当 :not() 没有被某些其他选择器(如类型选择器或类选择器)限定时,例如 .foo:not(div)。你可以更轻松地将样式应用于所有 h1 元素,并使用 div h1 覆盖它们。

Selectors 4 中,已经增强了 :not(),使其接受包含组合符号的完整复杂选择器,包括后代组合符号。是否将其实现到快速配置文件(因此 CSS)中尚待测试和确认,但一旦实现,您将能够使用它来排除具有特定祖先元素的元素。由于选择器的工作方式,否定必须在元素本身上进行而不是在祖先元素上进行才能可靠地工作,因此语法会略有不同:

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

任何熟悉 jQuery 的人都会很快指出,这个选择器在 jQuery 中可以使用。这是 Selector 3 的 :not() 和 jQuery 的 :not() 之间的许多差异之一,Selectors 4 旨在纠正这些差异。

5
提醒所有读者,目前大多数主流浏览器都已经支持复杂的:not()选择器。 - Drazen Bjelovuk

20

<html>元素不是<div>元素。 <body>元素也不是<div>元素。

因此,“具有非<div>祖先”的条件对于所有元素都成立。

除非您可以使用>(子项)选择器,否则我认为您不能完成您正在尝试做的事情 - 它并没有真正意义。在您的第二个示例中,<article>不是<div>,因此它也与*:not(div)匹配。


3
除了html元素(因为它是根元素,这里并不重要),"all elements" 指除此之外的所有元素。 - BoltClock

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