Changing the child element's CSS when the parent is hovered
JqueryCssJquery SelectorsParentJquery Problem Overview
First of all, I'm assuming this is too complex for CSS3, but if there's a solution in there somewhere, I'd love to go with that instead.
The HTML is pretty straightforward.
<div class="parent">
<div class="child">
Text Block 1
</div>
</div>
<div class="parent">
<div class="child">
Text Block 2
</div>
</div>
The child div is set to display:none; by default, but then changes to display:block; when the mouse is hovered over the parent div. The problem is that this markup appears in several places on my site, and I only want the child to be displayed if the mouse is over it's parent, and not if the mouse is over any of the other parents (they all have the same class name and no IDs).
I've tried using $(this)
and .children()
to no avail.
$('.parent').hover(function(){
$(this).children('.child').css("display","block");
}, function() {
$(this).children('.child').css("display","none");
});
Jquery Solutions
Solution 1 - Jquery
Why not just use CSS?
.parent:hover .child, .parent.hover .child { display: block; }
and then add JS for IE6 (inside a conditional comment for instance) which doesn't support :hover properly:
jQuery('.parent').hover(function () {
jQuery(this).addClass('hover');
}, function () {
jQuery(this).removeClass('hover');
});
Here's a quick example: Fiddle
Solution 2 - Jquery
No need to use the JavaScript or jquery, CSS is enough:
.child{ display:none; }
.parent:hover .child{ display:block; }
Solution 3 - Jquery
.parent:hover > .child {
/*do anything with this child*/
}
Solution 4 - Jquery
Use toggleClass()
.
$('.parent').hover(function(){
$(this).find('.child').toggleClass('color')
});
color
is the class. You can style the class as you like to achieve the behavior you want. The example demonstrates how class is added and removed upon mouse in and out.
Check Working example here.
where Solution 5 - Jquery
Not sure if there's terrible reasons to do this or not, but it seems to work with me on the latest version of Chrome/Firefox without any visible performance problems with quite a lot of elements on the page.
*:not(:hover)>.parent-hover-show{
display:none;
}
But this way, all you need is to apply parent-hover-show
to an element and the rest is taken care of, and you can keep whatever default display type you want without it always being "block" or making multiple classes for each type.
Solution 6 - Jquery
Stephen's answer is correct but here's my adaptation of his answer:
###HTML
parent 1
<div class="parent">
<p> parent 2 </p>
<div class="child">
Text Block 2
</div>
</div>
###CSS
.parent { width: 100px; min-height: 100px; color: red; }
.child { width: 50px; min-height: 20px; color: blue; display: none; }
.parent:hover .child, .parent.hover .child { display: block; }
###jQuery
//this is only necessary for IE and should be in a conditional comment
jQuery('.parent').hover(function () {
jQuery(this).addClass('hover');
}, function () {
jQuery(this).removeClass('hover');
});
You can see this example working over at jsFiddle.
Solution 7 - Jquery
I have what i think is a better solution, since it is scalable to more levels, as many as wanted, not only two or three.
I use borders, but it can also be done with whateever style wanted, like background-color.
With the border, the idea is to:
- Have a different border color only one div, the div over where the mouse is, not on any parent, not on any child, so it can be seen only such div border in a different color while the rest stays on white.
You can test it at: http://jsbin.com/ubiyo3/13
And here is the code:
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>Hierarchie Borders MarkUp</title>
<style>
.parent { display: block; position: relative; z-index: 0;
height: auto; width: auto; padding: 25px;
}
.parent-bg { display: block; height: 100%; width: 100%;
position: absolute; top: 0px; left: 0px;
border: 1px solid white; z-index: 0;
}
.parent-bg:hover { border: 1px solid red; }
.child { display: block; position: relative; z-index: 1;
height: auto; width: auto; padding: 25px;
}
.child-bg { display: block; height: 100%; width: 100%;
position: absolute; top: 0px; left: 0px;
border: 1px solid white; z-index: 0;
}
.child-bg:hover { border: 1px solid red; }
.grandson { display: block; position: relative; z-index: 2;
height: auto; width: auto; padding: 25px;
}
.grandson-bg { display: block; height: 100%; width: 100%;
position: absolute; top: 0px; left: 0px;
border: 1px solid white; z-index: 0;
}
.grandson-bg:hover { border: 1px solid red; }
</style>
</head>
<body>
<div class="parent">
Parent
<div class="child">
Child
<div class="grandson">
Grandson
<div class="grandson-bg"></div>
</div>
<div class="child-bg"></div>
</div>
<div class="parent-bg"></div>
</div>
</body>
</html>
Solution 8 - Jquery
If you're using Twitter Bootstrap styling and base JS for a drop down menu:
.child{ display:none; }
.parent:hover .child{ display:block; }
This is the missing piece to create sticky-dropdowns (that aren't annoying)
- The behavior is to:
- Stay open when clicked, close when clicking again anywhere else on the page
- Close automatically when the mouse scrolls out of the menu's elements.
Solution 9 - Jquery
To change it from css you dont even need to set the child class
.parent > div:nth-child(1) { display:none; }
.parent:hover > div:nth-child(1) { display: block; }
Solution 10 - Jquery
What did work for me was nth-of-type to target an specific element, a SVG icon and instead of using display:none; to avoid not finding it later, I used the fill color as the background color, so white in this case and then to target with css the parent and finding directly the SVG element with :nth-type-of(1)
HTML
<div class="feature-col">
<div class="feature-icon bg-primary bg-dark" style="border:0.125em white">
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="white" class="bi bi-laptop" viewBox="0 0 16 16"><path d="M13.5 3a.5.5 0 0 1 .5.5V11H2V3.5a.5.5 0 0 1 .5-.5h11zm-11-1A1.5 1.5 0 0 0 1 3.5V12h14V3.5A1.5 1.5 0 0 0 13.5 2h-11zM0 12.5h16a1.5 1.5 0 0 1-1.5 1.5h-13A1.5 1.5 0 0 1 0 12.5z"></path>
</svg>
</div>
<h5>Website Design and Hosting</h5>
<p>Some text in here that is a child element as well...</p>
<a href="javascript:void(0);" class="icon-link">Call to action</a>
</div>
CSS
.feature-col:hover svg:nth-of-type(1){
fill: #FF5B0D;
cursor:pointer;
}
JSFIDDLE to play with: https://jsfiddle.net/93de7zbc/6/
Solution 11 - Jquery
Try use the css visibility property to keep with the size div to be possible hover the element: Using CSS Visibility property
.child {
visibility: hidden;
}
.parent:hover .child {
visibility: visible;
}
<h3>Hover below</h3>
<div class="parent">
<div class="child">Text Block 1</div>
</div>
<div class="parent">
<div class="child">Text Block 2</div>
</div>