26

Hi: got some html like:

<div class="class" >
    <div class="class" >
    </div>
</div>

And some css like:

div.class:hover
{
    border-width:2px;
    border-style:inset;
    border-color:red;
}

When I hover over the inner div, both divs get the red border. Is it possible to stop the propagation and get the red border on the inner div using css?

Thanks.

EDIT : starting with the answer pointed to by borrible I ended up with:

    $("div.class").mouseover(
        function(e) {
            e.stopPropagation();
            $(this).css("border-color", "red");
        }).mouseout(
        function() {
            $(this).css("border-color", "transparent");
        });

Shame it's not css but does the job. Thanks everyone, didn't get what I wanted but learned lots of new stuff. Ain't stack overflow great :)

Patrick
  • 8,175
  • 7
  • 56
  • 72
  • 1
    Any specific reason as to why both divs need to have the same class? The css rule will apply to every element with the class "class". Will creating a different (dummy) class name help? – PhD Jul 13 '11 at 13:03
  • 2
    See http://stackoverflow.com/q/1327711/469210 for using JS to stop propagation in a similar situation. – borrible Jul 13 '11 at 13:04
  • @Nupul: there are various reasons, they could be worked round but probably easier to implement it using JS – Patrick Jul 13 '11 at 13:05

7 Answers7

7

Have a look at http://jsfiddle.net/n6rzA/

Code from there:

<div class="c">
    <div class="c"></div>
</div>

.c:hover {border:solid 1px red}
.c > .c:hover {border:solid 1px green}
imsky
  • 3,239
  • 17
  • 16
  • 2
    was just about to paste this very thing, :D – Phil Jul 13 '11 at 13:04
  • 8
    @imsky: I guess the OP **doesn't want** the red border when you hover over the inner (green) div...isn't it? I too was going to paste this very thing :) – PhD Jul 13 '11 at 13:08
  • 1
    +1 for awesome site, -1 for not answering the actual question asked. – BoltClock Jul 13 '11 at 13:08
  • +1 because I didn't know you could nest css like that but it doesn't let me change the border of the outer element when I go into the inner element – Patrick Jul 13 '11 at 13:09
  • @Patrick: That is the problem, and why you need to use JS to solve it. – BoltClock Jul 13 '11 at 13:09
  • @imsky: No, that disables the border on the inner `div`. The OP wants to disable the border on the outer `div` if the cursor is on the inner one. – BoltClock Jul 13 '11 at 13:10
  • @BoltClock, gotcha, I see the problem. @Patrick, without JS you'll have a tough go of it. – imsky Jul 13 '11 at 13:14
  • why wouldn't a similiar setup be working? My parent will not exhibit any hover changes, but all the children will – Sam Alexander Jan 23 '17 at 18:40
5

If the inner class is immediate child you can use the >. If it's not immediate child you can use space.

So in first case .class > class:hover { } and in second case .class .class:hover { }

First case : http://jsfiddle.net/wp4Jf/

Second case : http://jsfiddle.net/wp4Jf/2

Keep in mind that > works for ie8+

Sotiris
  • 38,986
  • 11
  • 53
  • 85
  • @BoltClock according http://reference.sitepoint.com/css/childselector is buggy, in the other hand quirksmode.org says that it works for ie7. – Sotiris Jul 13 '11 at 14:39
  • Well yeah, but that's quite an edge case (which may be used as an anti-IE7 hack). In normal circumstances it works fine. – BoltClock Jul 13 '11 at 14:43
2

The following selector should stop the propegation of the hover event.

div.class:not(:has(div.class:hover)):hover

it only selects those divs with the class class that are being hovered on, which do not have a child that is a div with the class class that is also being hovered on.

So basically you hover over a child the parent won't be selected (or in other words you stop propegation)

Only downside is, that browser-support for the :has() pseudo-class is not yet that great (especially older versions) - but I guess the further we go into the future the smaller this issue will get.

Lord-JulianXLII
  • 1,031
  • 1
  • 6
  • 16
1

Old question, but for those that land here I solved the issue by rethinking the html a bit to make the CSS simple. This solved my problem when creating html/css for nested ul/li tree views. Adding an item class div:

<div class="class" >
    <div class="item">Parent</div>

    <div class="class" >
      <div class="item">Child</div>
    </div>
</div>

Then I can apply CSS to "item" class and since item is not within item, ...within item, ...within item, the hover selector doesn't cascade up the node chain. So I colored the background of my tree view items on hover without splashing all parents.

guru_florida
  • 636
  • 5
  • 13
0

While :has is not supported by all major browsers, I made such workaround, which may not always fit though: nested elements have different hover color, i. e. all elements will have hover effect, but they will not merge. If you expect to have more than 5 levels, you can continue adding lines for deeper levels:

.class:hover {background-color:#000}
.class .class:hover {background-color:#111}
.class .class .class:hover {background-color:#000}
.class .class .class .class:hover {background-color:#000}
.class .class .class .class .class:hover {background-color:#000}
Vasya
  • 260
  • 1
  • 2
  • 13
-1

I got the desired result by reworking a bit the html and using only css.

The HTML:

<div class="wrapper" > 
  <div class="parent"></div>
  <div class="child"></div>
</div>

And the CSS:

.wrapper {
  height: 500px;
  width: 500px;
  background-color: lightblue;
  position: relative;
}

.parent {
  height: 250px;
  width: 250px;
  background-color: lightgreen;
  top: 3em;
  left: 3em;
  position: absolute;
}

.parent:hover {
  border: 3px red solid;
}

.child {
  height: 50px;
  width: 50px;
  background-color: lightgrey;
  top: 5em;
  left: 5em;
  position: absolute;
}

.child:hover {
  border: 3px red solid;
}

https://jsfiddle.net/rafaelrozon/pynngjpk/

Basically instead of nesting the divs they can be siblings and then you can use css to make them look nested.

I hope it helps others.

Rafael Rozon
  • 2,639
  • 1
  • 15
  • 27
-1

You can add or remove a CSS class to the parent, when the child is hovered or not. So, you can listen to the child's onmouseenter and onmouseleave, in order to set a state in your parent component. Then, depending on the state, you can add the "child-hovered" class to the parent.

At the parent's CSS, you can check if it's hovered and doesn't have the class "child-hovered":

.parent-div:not(.child-hovered):hover {
  background-color: gray;
}