悬停子元素时如何设置父元素的样式?


159

我知道不存在CSS父选择器,但是在没有此类选择器的子元素上悬停时是否可以为父元素设置样式?

举个例子:考虑一个删除按钮,将其悬停时将突出显示将要删除的元素:

<div>
    <p>Lorem ipsum ...</p>
    <button>Delete</button>
</div>

通过纯CSS,当鼠标悬停在按钮上方时,如何更改此部分的背景颜色?



Answers:


134

好吧,这个问题之前已经被问过很多次了,最简单的典型答案是:纯CSS无法做到。名称:级联样式表仅支持层叠方向的样式,不支持向上样式。

但是,在大多数情况下,如给定示例一样,需要这种效果的情况下,仍然有可能使用这些级联特性来达到所需的效果。考虑以下伪标记:

<parent>
    <sibling></sibling>
    <child></child>
</parent>

诀窍是为同级对象提供与父级相同的大小和位置,并设置同级而不是父级的样式。这看起来像是父样式!

现在,如何给同胞定型?

当孩子被悬停时,父母也是如此,但兄弟姐妹却没有。兄弟姐妹也一样。总结了三种样式化同级样式的CSS选择器路径:

parent sibling { }
parent sibling:hover { }
parent:hover sibling { }

这些不同的路径提供了一些不错的可能性。例如,在问题示例中释放此技巧将导致以下错误

div {position: relative}
div:hover {background: salmon}
div p:hover {background: white}
div p {padding-bottom: 26px}
div button {position: absolute; bottom: 0}

样式父图像示例

显然,在大多数情况下,此技巧取决于绝对定位的使用,以使兄弟姐妹具有与父对象相同的大小,并且仍然允许子对象出现在父对象中。

有时有必要使用更合格的选择器路径来选择特定的元素,如该小提琴所示,该小提琴在树形菜单中多次实现了该技巧。真的很好。


1
这对突出显示很有用,但是如果您尝试更改字体颜色将不起作用,对吗?
Jahanzeb Khan

1
@JahanzebKhan更改字体颜色没有问题
NGLN

116

我知道这是一个古老的问题,但我设法做到了没有伪子对象(而是伪包装器)。

如果你设置父是没有pointer-events,然后一个孩子divpointer-events设置为auto,它的工作原理:)
注意<img>标记(例如)不会做的伎俩。
还记得设置pointer-eventsauto对它们有自己的事件监听器,否则他们将失去他们的点击功能的其他孩子。

div.parent {  
    pointer-events: none;
}

div.child {
    pointer-events: auto;
}

div.parent:hover {
    background: yellow;
}    
<div class="parent">
  parent - you can hover over here and it won't trigger
  <div class="child">hover over the child instead!</div>
</div>

编辑:
正如Shadow Wizard亲切指出的那样:值得一提的是,这不适用于IE10及以下版本。(FF和Chrome的旧版本也是如此,请参见此处


3
值得一提的是,这不适用于IE10及以下版本。(也有FF和Chrome的旧版本,请参见此处
Shadow Wizard为您

2
将指针事件设置为none也意味着该元素上的事件侦听器将无法工作。
rhazen

1
@rhazen你是完全正确的。尽管根据我的经验,这种用法通常与单个单击区域/元素相关,所以您可以将单击侦听器分配给父对象
guy_m

如果我有两个级别的父级,child1和child1的子级,该怎么办。我没有将指针事件添加到父级,而将指针事件自动添加到了子级。我想悬停child1除了孩子1.演示这里的孩子:codepen.io/lion5893/pen/WNQgyVx
纳姆·勒QUY

13

另一种更简单的方法(针对一个老问题)
将元素放置为同级并使用:

相邻的同级选择器+常规同级选择器~

<div id="parent">
  <!-- control should come before the target... think "cascading" ! -->
  <button id="control">Hover Me!</button>
  <div id="target">I'm hovered too!</div>
</div>
#parent {
  position: relative;
  height: 100px;
}

/* Move button control to bottom. */
#control {
  position: absolute;
  bottom: 0;
}

#control:hover ~ #target {
  background: red;
}

在此处输入图片说明

演示小提琴在这里


1
值得注意的是,这仅适用于#targets在DOM中的#control之后(即,您不能影响以前的兄弟姐妹,而只能影响后面的兄弟姐妹)
Gio

10

没有用于选择所选孩子的父母的CSS选择器。

你可以用JavaScript做到


3
真正。像$(child).hover(function(){$(this).closest(parentSelector).addClass('hoverClass')},function(){$(this).closest(parentSelector).removeClass('hoverClass' )});
Aamir Afridi 2014年

8
@AamirAfridi虽然这不是纯JS,但您必须使用jQuery。
Ivotje50 2015年

6

如前所述,“没有CSS选择器用于选择选定孩子的父母”。

所以你要么:


这是javascript / jQuery解决方案的示例

在JavaScript方面:

$('#my-id-selector-00').on('mouseover', function(){
  $(this).parent().addClass('is-hover');
}).on('mouseout', function(){
  $(this).parent().removeClass('is-hover');
})

在CSS方面,您将拥有以下内容:

.is-hover {
  background-color: red;
}

3

此解决方案完全取决于设计,但是如果您有一个父div并希望在悬停孩子时更改背景,则可以尝试使用::after/ 模仿父::before

<div class="item">
    design <span class="icon-cross">x</span>
</div>

CSS:

.item {
    background: blue;
    border-radius: 10px;
    position: relative;
    z-index: 1;
}
.item span.icon-cross:hover::after {
    background: DodgerBlue;
    border-radius: 10px;
    display: block;
    position: absolute;
    z-index: -1;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    content: "";
}

在这里查看完整的小提琴示例


-1

适用于不需要纯CSS解决方案的人的简单jquery解决方案:

    $(".letter").hover(function() {
      $(this).closest("#word").toggleClass("hovered")
    });
.hovered {
  background-color: lightblue;
}

.letter {
  margin: 20px;
  background: lightgray;
}

.letter:hover {
  background: grey;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="word">
  <div class="letter">T</div>
  <div class="letter">E</div>
  <div class="letter">S</div>
  <div class="letter">T</div>
</div>


-8

这在Sass中非常容易做到!请勿深入研究JavaScript。sass中的&选择器正是这样做的。

http://thesassway.com/intermediate/referencing-parent-selectors-using-ampersand


6
-1 Sass不会为CSS添加更多功能,而只是使编写变得更容易。您可以在sass中做的所有事情都可以在css中完成,反之亦然。
Dastur'9

3
@Dastur给定变量和mixins,我想说Sass给CSS增加了很多。您可以在CSS中完成所有操作,就像仍然可以使用普通的旧C语言编写复杂的软件一样。现代语言在不启用以前无法完成的功能的情况下增加了很多。与Sass和CSS相同。
Cobus Kruger

6
@Cobus Kruger您的部分正确,但您无法进行比较。尽管c ++ c#和javascript之类的语言可能基于C,但它们在运行时不会变成C。Sass在运行时之前在CSS中转换,因此您永远不会真正加载Sass样式表,仅是一个CSS样式表。
Dastur '16
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.