如何选择作为锚元素的直接父元素的<li>元素?

例如,我的CSS应该是这样的:

li < a.active {
    property: value;
}

很显然,JavaScript有很多方法可以做到这一点,但我希望有某种变通方法可以在CSS Level 2中使用。

我正在尝试设置样式的菜单被CMS弹出,因此我无法将活动元素移动到<li>元素。。。(除非我对菜单创建模块进行主题化,否则我不想这样做)。


当前回答

目前还没有父选择器&它甚至没有在W3C的任何讨论中讨论。您需要了解浏览器如何评估CSS,才能真正了解我们是否需要它。

这里有很多技术解释。

Jonathan Snook解释了如何评估CSS。

Chris Coyier谈家长选择。

Harry Roberts再次谈到了如何编写高效的CSS选择器。

但妮可·沙利文对积极趋势有一些有趣的事实。

这些人都是前端开发领域的顶级人物。

其他回答

我知道OP正在寻找CSS解决方案,但使用jQuery很容易实现。在我的例子中,我需要为包含在子<li>中的<span>标记找到<ul>父标记。jQuery具有:has选择器,因此可以通过它包含的子项来标识父项:

$("ul:has(#someId)")

将选择具有id为someId的子元素的ul元素。或者,为了回答最初的问题,应该使用以下方法(未经测试):

$("li:has(.active)")

这是Selectors Level 4规范中讨论最多的方面。这样,选择器就可以通过在给定的选择器(!)后面使用感叹号来根据其子元素设置元素的样式。

例如:

body! a:hover{
   background: red;
}

如果用户悬停在任何锚点上,将设置红色背景色。

但我们必须等待浏览器的实现:(

更新2022 CSS选择器4

在CSS Selectors 4规范中,CSS引入了一个名为:has()的新选择器,它最终允许我们选择父级。这意味着我们将能够针对一个包含特定子元素的CSS元素。这在Safari和Chrome105中都已得到支持。显示完整的支撑台在这里

父选择器工作

在CSS中,如果我们想选择一些东西,我们使用DOM下面的选择器。

例如,在div标记中选择p标记如下所示:

 div p {
   color: red;
}

不过,到目前为止,我们还无法真正选择其中包含p标记的div标记,这意味着我们不得不求助于Javascript。没有在CSS中实现这一点的主要原因是,这是一个相当昂贵的操作。CSS解析速度相对较快,但选择父标记需要相对较大的处理量。

使用:has选择器,我们现在可以选择具有p子级的div元素,或选择器的任何正常组合。

例如,选择带有子p的div现在看起来像这样:

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

这将使任何带有子p的div变为红色。

将父选择与其他选择器组合

就像任何其他CSS选择器一样,我们可以针对特定情况组合这些选择器。例如,如果只选择具有直接span子级的div标记:

div:has(> span) {
  color: red;
}

正如:的词汇所暗示的,它不仅仅局限于父母的选择。

例如,下面我们可以选择一个span,该span:有一个同级div:

span:has(+ div) {
color: red;
}

甚至,通过使用:not()选择器选择一个没有子元素的元素。

例如,下面将选择任何没有p子级的div:

div:not(:has(p)) {
 color: red;
}

选择仅包含CSS中文本的元素

CSS中一个非常常见的问题是:empty标记不选择包含任何文本的元素,因此有时元素可以包含一个空格,而:empty将不适用。has选择器使我们能够选择只包含文本节点而不包含其他子元素的元素。

虽然这并不是简单的空元素和空格的完美解决方案(因为这将选择任何只包含文本的元素,而不包含额外的HTML DOM元素),但它确实让我们能够选择只包含文本节点的DOM元素,这在以前是不可能的。我们可以通过以下代码实现这一点:

div:not(:has(*)) {
  background: green;
}

可以使用:has()CSS伪类

但它的浏览器支持有限(目前只有Chrome/Edge/Safari)。

尝试将a切换为块显示,然后使用所需的任何样式。a元素将填充li元素,您可以根据需要修改其外观。不要忘记将li padding设置为0。

li {
  padding: 0;
  overflow: hidden;
}
a {
  display: block;
  width: 100%;
  color: ..., background: ..., border-radius: ..., etc...
}
a.active {
  color: ..., background: ...
}