有一个CSS父选择器吗?

问题描述 投票:2791回答:27

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

在示例中,我的CSS将是这样的:

li < a.active {
    property: value;
}

显然有一些方法可以使用JavaScript来实现这一点,但我希望CSS Level 2本身存在某种解决方法。

我尝试设置的菜单是由CMS发出的,所以我无法将活动元素移动到<li>元素...(除非我主题菜单创建模块,我宁愿不这样做)。

有任何想法吗?

css css-selectors
27个回答
2244
投票

目前无法在CSS中选择元素的父级。

如果有办法,它将在当前的CSS选择器规范中:

与此同时,如果您需要选择父元素,则必须使用JavaScript。


Selectors Level 4 Working Draft包括一个与:has()相同的jQuery implementation伪类。截至2019年,this is still not supported by any browser

使用:has()原始问题可以通过以下方法解决:

li:has(> a.active) { /* styles to apply to the li tag */ }

25
投票

据我所知,不是在CSS 2中。 CSS 3具有更强大的选择器,但并非在所有浏览器中始终如一地实现。即使使用改进的选择器,我也不相信它会完全符合您在示例中指定的内容。


23
投票

我知道OP正在寻找一个CSS解决方案,但使用jQuery实现起来很简单。在我的情况下,我需要找到包含在孩子<ul>中的<span>标签的<li>父标签。 jQuery有:has选择器,因此它可以通过它包含的子节点识别父节点:

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

将选择具有id为someId的子元素的ul元素。或者回答原始问题,类似下面的内容应该可以做到(未经测试):

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

20
投票

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

例如:

body! a:hover{
   background: red;
}

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

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


19
投票

您可以尝试使用超链接作为父级,然后在悬停时更改内部元素。像这样:

a.active h1 {color:red;}

a.active:hover h1 {color:green;}

a.active h2 {color:blue;}

a.active:hover h1 {color:yellow;}

这样,您可以根据父元素的翻转更改多个内部标记中的样式。


16
投票

如果后代具有焦点,则伪元素:focus-within允许选择父元素。

如果元素具有tabindex属性,则可以对其进行聚焦。

Browser support for focus-within

Tabindex

.click {
  cursor: pointer;
}

.color:focus-within .change {
  color: red;
}

.color:focus-within p {
  outline: 0;
}
<div class="color">
  <p class="change" tabindex="0">
    I will change color
  </p>
  <p class="click" tabindex="1">
    Click me
  </p>
</div>

13
投票

有人提出这样的建议吗?只是水平菜单的想法......

HTML的一部分

<div class='list'>
  <div class='item'>
    <a>Link</a>
  </div>
  <div class='parent-background'></div>
  <!-- submenu takes this place -->
</div>

CSS的一部分

/* hide parent backgrounds... */
.parent-background {
  display: none; }

/* ... and show it when hover on children */
.item:hover + .parent-background {
  display: block;
  position: absolute;
  z-index: 10;
  top: 0;
  width: 100%; }

Updated demo and the rest of code

Another example如何使用文本输入 - 选择父字段集


13
投票

目前没有父选择器,甚至在W3C的任何谈话中都没有讨论。您需要了解浏览器如何评估CSS以实际了解我们是否需要它。

这里有很多技术解释。

Jonathan Snook explains how CSS is evaluated

Chris Coyier on the talks of Parent selector

Harry Roberts again on writing efficient CSS selectors

但是Nicole Sullivan has some interesting facts on positive trends

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


11
投票

从技术上讲,没有直接的方法可以做到这一点,你可以用jquery或javascript对它进行排序。

不过,你也可以这样做。

a.active h1 {color:blue;}
a.active p {color: green;}

jQuery的

$("a.active").parents('li').css("property", "value"); 

如果你想使用jQuery实现这一点,这里是jQuery parent selector的参考


11
投票

有一个扩展CSS的插件,包括一些非标准功能,可以在设计网站时提供帮助。它被称为EQCSS

EQCSS添加的一个东西是父选择器。它适用于所有IE8及更高版本的浏览器。这是格式:

@element 'a.active' {
  $parent {
    background: red;
  }
}

所以这里我们已经在每个元素a.active上打开了一个元素查询,对于查询中的样式,像$parent这样的东西是有意义的,因为它有一个参考点。浏览器可以找到父级,因为它与JavaScript中的parentNode非常相似。

Here's a demo of $parentanother $parent demo that works in IE8,以及a screenshot in case you don't have IE8 around to test with

EQCSS还包括meta-selectors $prev用于选定元素之前的元素,$this仅用于那些与元素查询匹配的元素,等等。


9
投票

W3C排除了这样一个选择器,因为它会对浏览器产生巨大的性能影响。


143
投票

我认为你不能只选择css中的父级。

但是,由于你似乎已经有一个.active类,将该类移动到li(而不是a)会不会更容易?这样你只能通过css访问lia


7
投票

简短的回答是否定的,我们在CSS的这个阶段没有parent selector,但如果你没有交换元素或类,第二个选项是使用JavaScript,如下所示:

var activeATag = Array.prototype.slice.call(document.querySelectorAll('a.active'));

activeATag.map(function(x) {
  if(x.parentNode.tagName === 'LI') {
    x.parentNode.style.color = 'red'; //your property: value;
  }
});

或者在您的应用程序中使用jQuery时更短的方法:

$('a.active').parents('li').css('color', 'red'); //your property: value;

5
投票

虽然目前标准CSS中没有父选择器,但我正在研究一个名为ax的(个人)项目(即增强型CSS选择器语法/ ACSSSS),它在7个新的选择器中包括:

  1. 一个直接的父选择器<(它启用与>相反的选择)
  2. 任何祖先选择器^(它使相反的选择[SPACE]

ax目前处于相对早期的BETA发展阶段。

在这里看一个演示:

http://rounin.co.uk/projects/axe/axe2.html

(比较左边的两个列表用标准选择器设置,右边的两个列表用斧头选择器设置)


4
投票

这是使用pointer-eventshover的黑客攻击:

<!doctype html>
<html>
	<head>
		<title></title>
		<style>
/* accessory */
.parent {
	width: 200px;
	height: 200px;
	background: gray;
}
.parent, 
.selector {
	display: flex;
	justify-content: center;
	align-items: center;
}
.selector {
	cursor: pointer;
	background: silver;
	width: 50%;
	height: 50%;
}
		</style>
		<style>
/* pertinent */
.parent {
	background: gray;
	pointer-events: none;
}
.parent:hover {
	background: fuchsia;
}
.parent 
.selector {
	pointer-events: auto;
}
		</style>
	</head>
	<body>
		<div class="parent">
			<div class="selector"></div>
		</div>
	</body>
</html>

4
投票

它现在是2019年,而latest draft of the CSS Nesting Module实际上有这样的东西。介绍@nest at-rules。

3.2。嵌套规则:@nest

虽然直接嵌套看起来不错,但它有点脆弱。不允许使用某些有效的嵌套选择器,如.foo&,并且以某些方式编辑选择器会使规则意外无效。同样,有些人发现嵌套具有挑战性,可以在视觉上区别于周围的声明。

为了解决所有这些问题,本规范定义了@nest规则,该规则对如何有效地嵌套样式规则施加的限制较少。它的语法是:

@nest = @nest <selector> { <declaration-list> }

@nest规则的功能与样式规则相同:它以选择器开头,并包含适用于选择器匹配的元素的声明。唯一的区别是@nest规则中使用的选择器必须是包含嵌套的,这意味着它在某处包含嵌套选择器。如果所有选择器都包含嵌套,则选择器列表将包含嵌套。

(从上面的URL复制并粘贴)。

本规范下有效选择器的示例:

.foo {
  color: red;
  @nest & > .bar {
    color: blue;
  }
}
/* equivalent to
   .foo { color: red; }
   .foo > .bar { color: blue; }
 */

.foo {
  color: red;
  @nest .parent & {
    color: blue;
  }
}
/* equivalent to
   .foo { color: red; }
   .parent .foo { color: blue; }
 */

.foo {
  color: red;
  @nest :not(&) {
    color: blue;
  }
}
/* equivalent to
   .foo { color: red; }
   :not(.foo) { color: blue; }
 */

3
投票

不,你不能只在css中选择父。

但是,由于你似乎已经有一个.active类,将这个类移动到li(而不是a)会不会更容易?这样你只能通过css访问lia


3
投票

至少包括CSS3在内,你不能选择那样的CSS3。但是现在在JS中可以很容易地完成它,你只需要添加一些vanilla JavaScript,注意代码很短。

      cells = document.querySelectorAll('div');
              [].forEach.call(cells, function (el) {
              //console.log(el.nodeName)
                if (el.hasChildNodes() && el.firstChild.nodeName=="A") {
                console.log(el)};
            });
            <div>Peter</div>
            <div><a href="#">Jackson link</a></div>
            <div>Philip</div>
            <div><a href="#">Pullman link</a></div>

2
投票

在SASS中使用&符号是可能的:

h3
  font-size: 20px
  margin-bottom: 10px
  .some-parent-selector &
    font-size: 24px
    margin-bottom: 20px

CSS输出:

h3 {
  font-size: 20px;
  margin-bottom: 10px;
}
.some-parent-selector h3 {
  font-size: 24px;
  margin-bottom: 20px;
}

-2
投票

在CSS中,我们可以在层次结构中级联到属性,但不能在相反的方向上级联。要修改子事件的父样式,可能使用jQuery。

$el.closest('.parent').css('prop','value');

115
投票

你可以使用这个script

*! > input[type=text] { background: #000; }

这将选择文本输入的任何父级。但是等等,还有更多。如果需要,可以选择指定的父级:

.input-wrap! > input[type=text] { background: #000; }

或者在它处于活动状态时选择它:

.input-wrap! > input[type=text]:focus { background: #000; }

看看这个HTML:

<div class="input-wrap">
    <input type="text" class="Name"/>
    <span class="help hide">Your name sir</span>
</div>

你可以在span.help处于活动状态时选择那个input并显示它:

.input-wrap! .help > input[type=text]:focus { display: block; }

还有更多功能;只需查看插件的文档。

顺便说一句,它适用于IE。


94
投票

正如其他几个人所提到的,没有办法仅使用CSS来设置元素的父/的样式,但以下与jQuery一起使用:

$("a.active").parents('li').css("property", "value");

60
投票

没有父选择器;只是没有以前的兄弟选择器的方式。没有这些选择器的一个好理由是浏览器必须遍历元素的所有子元素以确定是否应该应用类。例如,如果您写道:

body:contains-selector(a.active) { background: red; }

然后浏览器必须等到它加载并解析所有内容,直到</body>确定页面是否应该是红色。

本文Why we don't have a parent selector详细解释了它。


49
投票

在css2中没有办法做到这一点。你可以将类添加到li并引用a

li.active > a {
    property: value;
}

33
投票

尝试将a切换到block显示,然后使用您想要的任何样式。 a元素将填充li元素,您将能够根据需要修改它的外观。不要忘记将li填充设置为0。

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

33
投票

CSS选择器“General Sibling Combinator”可以用于你想要的东西:

E ~ F {
    property: value;
}

这匹配任何前面有F元素的E元素。


30
投票

是的::has()

浏览器支持:none

© www.soinside.com 2019 - 2024. All rights reserved.