我想做一个选择器,它将选择所有的元素,如果他们有一个特定的子元素。例如,选择所有<div>和子<span>。

可能吗?


是否可以选择包含特定子元素的元素?

不幸的是,还没有。

CSS2和CSS3选择器规范不允许任何类型的父选择。


关于规格变更的说明

这是一个关于这篇文章准确性的免责声明。CSS中的父选择器已经讨论了很多年。由于没有达成共识,变化不断发生。我将尝试保持这个答案的最新,但请注意,由于规范的变化,可能有不准确的地方。


一个较旧的“selector Level 4 Working Draft”描述了一个特性,即指定选择器的“主题”的能力。此特性已被删除,并且将无法用于CSS实现。

subject将是selector链中的元素,它将有样式应用于它。

示例HTML

<p><span>lorem</span> ipsum dolor sit amet</p>
<p>consecteture edipsing elit</p>

这个选择器将为span元素设置样式

p span {
    color: red;
}

这个选择器将设置p元素的样式

!p span {
    color: red;
}

最近的“选择器4级编辑稿”包括“关系伪类::has()”

:has()允许作者根据元素的内容选择元素。我的理解是,选择它是为了兼容jQuery的自定义:has()伪选择器*。

在任何情况下,继续上面的例子,选择包含span的p元素可以使用:

p:has(span) {
    color: red;
}

*这让我想知道,如果jQuery实现了选择器主题,主题是否会保留在规范中。


我同意这在一般情况下是不可能的。

CSS3能做的唯一一件事(在我的例子中有帮助)是选择没有子元素:

table td:empty
{
   background-color: white;
}

或有子女(含文字):

table td:not(:empty)
{
   background-color: white;
}

更新2022年12月-只有Firefox不支持has()

:has()伪选择器是在CSS selector 4规范中提出的,一旦实现就会解决这个用例。

要使用它,我们可以这样写:

.foo > .bar:has(> .baz) { /* style here */ }

在像这样的结构中:

<div class="foo">
  <div class="bar">
    <div class="baz">Baz!</div>
  </div>
</div>

这个CSS将以.bar div为目标,因为它既有父元素。foo,而且从它在DOM中的位置,> .baz将解析为有效的元素目标。


原始答案(出于历史目的)-这部分不再准确

为了完整起见,我想指出,在Selectors 4规范(目前正在建议中)中,这将成为可能。具体来说,我们将获得主题选择器,它将以以下格式使用:

!div > span { /* style here */

!在div选择器之前指出它是要样式化的元素,而不是span。不幸的是,没有现代浏览器(截至本文发布时)将此实现为CSS支持的一部分。但是,如果您想进一步探索,可以通过名为Sel的JavaScript库提供支持。