Changing the child element's CSS when the parent is hovered

JqueryCssJquery SelectorsParent

Jquery 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; }

SEE DEMO

Solution 3 - Jquery

.parent:hover > .child {
    /*do anything with this child*/
}

Solution 4 - Jquery

Use toggleClass().

$('.parent').hover(function(){
$(this).find('.child').toggleClass('color')
});

where 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.

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

Text Block 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:
  1. Stay open when clicked, close when clicking again anywhere else on the page
  2. 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

Using CSS Visibility property
Try use the css visibility property to keep with the size div to be possible hover the element:

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionHartley BrodyView Question on Stackoverflow
Solution 1 - JqueryStephenView Answer on Stackoverflow
Solution 2 - JqueryAli AdraviView Answer on Stackoverflow
Solution 3 - JqueryAmir RahmanView Answer on Stackoverflow
Solution 4 - JqueryHusseinView Answer on Stackoverflow
Solution 5 - JqueryBrian LeishmanView Answer on Stackoverflow
Solution 6 - JqueryRoger RoelofsView Answer on Stackoverflow
Solution 7 - Jqueryz666zz666zView Answer on Stackoverflow
Solution 8 - JqueryR TobinView Answer on Stackoverflow
Solution 9 - Jqueryhamboy75View Answer on Stackoverflow
Solution 10 - JqueryJean G.TView Answer on Stackoverflow
Solution 11 - JqueryFábio Ribeiro de CarvalhoView Answer on Stackoverflow