首页 文章

有一个CSS父选择器吗?

提问于
浏览
2642

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

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

li < a.active {
    property: value;
}

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

我正在尝试设置样式的菜单正在由CMS喷出,因此我无法将活动元素移动到 <li> 元素...(除非我主题菜单创建模块,我宁愿不这样做) .

有任何想法吗?

26 回答

  • 40

    简短的回答是 NO ,我们在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;
    
  • 15

    那里's a plugin that extends CSS to include some non-standard features that can really help when designing websites. It'被称为EQCSS .

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

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

    所以这里我们已经在每个元素 a.active 上打开了一个元素查询,对于该查询中的样式, $parent 之类的东西是有意义的,因为's a reference point. The browser can find the parent, because it'与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 仅用于与元素查询匹配的元素,等等 .

  • 0

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

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

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

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

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


    Selectors Level 4 Working Draft包含 :has() 伪类,其作用与jQuery implementation相同 . 截至2018年, this is still not supported by any browser .

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

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

    正如其他几个人所提到的,没有't a way to style an element'的父/只使用CSS,但以下内容适用于jQuery

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

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

    不过,你也可以这样做 .

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

    jQuery

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

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

  • 0

    尝试将 a 切换为 block 显示,然后使用您想要的任何样式 . a 元素将填充 li 元素,您将能够修改它's look as you want. Don' t忘记将 li 填充设置为0 .

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

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

    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如何将其与文本输入一起使用 - 选择父字段集

  • 104

    伪元素 :focus-within 允许在后代具有焦点时选择父元素 .

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

    Browser support for focus-within

    Tabindex

    Example

    .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>
    
  • 9

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

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

  • 25

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

    a.active h1 {color:red;}
    
    a.active:hover h1 {color:green;}
    
    a.active h2 {color:blue;}
    
    a.active:hover h1 {color:yellow;}
    

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

  • 1

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

  • 2130

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

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

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

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

  • 9

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

    例如:

    body! a:hover{
       background: red;
    }
    

    如果用户将鼠标悬停在任何锚点上,则会设置红色背景颜色 .

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

  • 7

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

    li.active > a {
        property: value;
    }
    
  • 0

    据我所知,不是在CSS 2中 . CSS 3具有更强大的选择器,但并非在所有浏览器中始终如一地实现 . 即使有改进的选择器,我也不相信它会完全实现你已经在你的例子中指定了 .

  • -3

    在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;
    }
    
  • 26

    你可以使用这个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>
    

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

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

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

    顺便说一下,它适用于IE .

  • 50

    至少包括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>
    
  • 16

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

    • 一个直接父选择器 < (启用相反的选择 >

    • 任何祖先选择器 ^ (启用相反的选择 [SPACE]

    axe 目前处于相对较早的BETA发展阶段 .

    在这里看一个演示:

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

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

  • 9

    目前没有父选择器,甚至没有在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 .

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

  • 3

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

    E ~ F {
        property: value;
    }
    

    这匹配任何 F 元素前面的 F 元素 .

  • 0

    这是一个使用 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>
    
  • 20

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

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

  • 6

    是的::has()

    浏览器支持:none

  • 15

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

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

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

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

相关问题