1

With the following code below I want to be able to apply a CSS style to the parent li class="parent" item in the list. But only when the user is hovering over the child li class="child" items for that particular parent.

It's my understanding that this won't be possible using just CSS, but does anyone know of a potential Javascript solution (ideally using jQuery, as we're already using this library on our website)

Thanks!

<ul>
    <li class="parent"><a href="URL" >Main Link</a>
         <ul class="sub-menu">
             <li class="child"><a href="URL" >Link</a></li>
         </ul>
    </li>
</ul>
  • Note that while you have put `class="parent"` in your markup, there's really no reason to do this. As the answers below show, use `closest('li')` to find the nearest owning item. You don't even need `class="child"`, as you could do `$('li li').hover(…);` – Phrogz Feb 24 '12 at 04:37

5 Answers5

2

You heard right—CSS doesn't allow you to traverse upward on the DOM tree, only downward. As in, you can select children, but not parents.

Here's one method to do it with jQuery:

$("li.child").on("hover", function(){
    $(this)
        .closest("li.parent")
        .css({
            // styling here
        });
});

What we do is select the li element with the class child. We bind the hover event to it and fire a function when that event occurs. The function finds the closest parent of the child li with the class parent, and we change its CSS.

More on on() here, closest() here, and css() here.

Also keep in mind that for earlier versions of jQuery, you can use bind() or delegate().

EDIT: To have it change on mouseover and mouseout:

$("li.child").on("mouseover mouseout", function(){
    $(this)
        .closest("li.parent")
        .toggleClass("myClass");
});

And what you do here is define the class myClass in your CSS. toggleClass adds the class if it doesn't already exist on the element and removes it otherwise. It's self explanatory. This way, you save a few bytes and use more preferred and recommended jQuery.

Purag
  • 16,941
  • 4
  • 54
  • 75
  • Minor clarification: with the adjacent sibling selector in CSS you can traverse 'downward' in source code but 'sideways' in terms of the DOM tree. – Phrogz Feb 24 '12 at 04:28
2

You can do something like this:

$('li.child').hover(function() {
   $(this).closest('.parent').addClass('red');
}, function() {
   $(this).closest('.parent').removeClass('red');    
});

Working example:

icyrock.com
  • 27,952
  • 4
  • 66
  • 85
0

Something like this should work:

//The hover method takes two functions, one it does on mouseover
//and the other executes on mouseout
​$(".child").hover(
    function(){//get the parent -> then get its parent (the li)
        $(this).parent().parent().addClass("parent");//add the class to it
    },
    function(){//this executes on mouseout
        $(this).parent().parent().removeClass("parent");
    }//remove the class..
);​

You could use the .parent class as a marker and use jquery's class selector or you could use a variety of other selectors to get to that parent.

See demo : http://jsfiddle.net/D8zTE/1/

gideon
  • 19,329
  • 11
  • 72
  • 113
  • True, but I assumed he'd want to just select two levels from the child without being concerned about what class it has. – gideon Feb 26 '12 at 08:24
0
$("li.child").hover(function () {
    $(this).parents('li.parent').addClass('parentHoverClass');
    //Alternatively, you could apply inline styles to the <li> like this:
    //$(this).parents('li.parent').css({
    //  'display': 'block',
    //  'color': '#FF00FF',
    //  'text-decoration': 'underline'
    //});
}, function () {
    $(this).parents('li.parent').removeClass('parentHoverClass');
    //Or, you could reset inline styles to the <li> like this:
    //$(this).parents('li.parent').css({
    //  'display': 'inline',
    //  'color': '#00FF00',
    //  'text-decoration': 'none'
    //});
});
pete
  • 24,141
  • 4
  • 37
  • 51
-1

use the jquery hover for this.

$(".child").hover(function(){
$(".parent").css() //check the jquery css api for the styling options
})
XepterX
  • 1,017
  • 6
  • 16
  • This will select all `.parent` elements in the entire DOM. – Phrogz Feb 24 '12 at 04:28
  • 1
    i'm assuming there is only one class called parent from what the he asked. there is nothing wrong with the answer, just too general – XepterX Feb 24 '12 at 04:33