Reputation: 371231
This is a common question. It almost always gets immediately closed as a duplicate of this question: Is there a CSS parent selector?
The duplicate does a good job pointing out that parent elements cannot be targeted with CSS. But it provides little to no guidance for the original question, which may be caught in the XY problem.
In this particular case...
How can the background color of the parent be changed when hovering the child?
...there is at least one CSS solution that may solve the problem.
<div>
<a href="#">Anchor Text</a>
</div>
Upvotes: 11
Views: 22857
Reputation: 371231
Although you can't select parent elements with CSS, you may be able to accomplish the task with another method.
You want the background color of the parent to change when a child is hovered.
Consider using the spread-radius
value of the CSS box-shadow
property.
By creating a huge spread radius, you can change the color of the surrounding area (which is no different visually than the parent element).
div {
overflow: hidden; /* 1 */
}
a:hover {
box-shadow: 0 0 0 1000px red; /* 2 */
}
/* non-essential decorative styles */
div {
height: 150px;
width: 150px;
border: 1px dashed black;
display: flex;
justify-content: center;
align-items: center;
}
<div>
<a href="http://www.stackoverflow.com/">Anchor Text</a>
</div>
Notes:
overflow: hidden
to limit child's box shadowbox-shadow
values are as follows:<box-shadow> : <offset-x> <offset-y> <blur-radius> <spread-radius> <color>
blur-radius
~ makes the shadow increasingly bigger and transparentspread-radius
~ makes the shadow expand (without fading)In this case, the first three values don't matter.
What you need is for the spread-radius
to grow a lot, then have it clipped by the container with overflow: hidden
.
And what if there's another element in the container?
<div>
<h2>Hello</h2>
<a href="http://www.google.com">Anchor Text</a>
</div>
div {
overflow: hidden;
}
a:hover {
box-shadow: 0 0 0 1000px red;
}
div {
height: 150px;
width: 150px;
border: 1px dashed black;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
<div>
<h2>Hello</h2>
<a href="http://www.stackoverflow.com/">Anchor Text</a>
</div>
You can apply a z-index
to the sibling.
h2 { z-index: 1; }
And, because the elements happen to be in a flex container in this example, they don't need to be positioned for z-index
to work.
h2 { z-index: 1; }
div {
overflow: hidden;
}
a:hover {
box-shadow: 0 0 0 1000px red;
}
div {
height: 150px;
width: 150px;
border: 1px dashed black;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
<div>
<h2>Hello</h2>
<a href="http://www.stackoverflow.com/">Anchor Text</a>
</div>
Upvotes: 8
Reputation: 24692
pointer-events
and :hover
Compatibility of pointer-events: caniuse.com. Tested working on IE 11 and Edge, Chrome and Firefox.
Set pointer-events: none
on the div. The div will now ignore :hover
.
div {
pointer-events: none;
}
Set the parent background to change on hover
div:hover {
background: #F00;
}
Set pointer-events: auto
on the child so that the hover event is triggered only when the child is hovered
div > a {
pointer-events: auto;
}
This works because the div is hovered when its child is hovered, and pointer events are activated with auto
only on that child. Otherwise the parent ignores its hover pseudo-class.
Note: IE 11 and Edge require the child element to be
display: inline-block
ordisplay: block
for pointer events to work.
div {
height: 200px;
width: 200px;
text-align: center;
pointer-events: none;
}
div:hover {
background: #F00;
}
div > a {
pointer-events: auto;
display: inline-block;
}
<div>
<h1>Heading</h1>
<a href="#">Anchor Text</a>
</div>
Upvotes: 15
Reputation: 38252
Another approach if you just want to change the background of the parent element is to fake it with a pseudo-element, consider this structure:
.div1 {
position: relative;
padding:2em;
color:white;
}
a {
color:white;
font-family:sans-serif;
}
a:before {
content:"";
position:absolute;
left:0;
top:0;
height:100%;
width:100%;
background:red;
z-index:-1;
transition:background .5s linear;
}
a:hover:before {
background:purple;
}
<div class="div1">
<div class="div2">
<h2>Here Some Title</h2>
<a href="#">Hover Me</a>
</div>
</div>
Upvotes: 6