7

In css, how can I stop the :hover event being triggered in a parent element when a child event is hovered, so that it only gets triggered when the parent itself gets hovered? In this case my child element is actually positioned outside it's parent element with absolute positioning, so it's a bit weird when the parent changes when the child gets hovered.

I made a JSFiddle to illustrate the problem.

Here's a JSFiddle of the used solution to my example.

davmac
  • 20,150
  • 1
  • 40
  • 68
CupOfTea696
  • 1,266
  • 3
  • 14
  • 29

3 Answers3

17

There is a pure css solution (even two in fact) but both come at a cost.

  1. You can add pointer-events:none; to your child element - but it will not respond to it's own hover styles either. Pointer-events unfortunately are not supported in IE below version 11 (http://caniuse.com/#search=pointer-events).

  2. Wrap content of your parent element (apart from positioned child) in another one (thats the cost of this method) and apply hover styles to this wrapper.

Examples of both methods here.

.parent-2,
.parent { position:relative; background:#ddd; width:100px; height:100px; }
.parent:hover { background:blue; }
.child { position:absolute; top:0; left:130px; width:100px; height:50px; border:1px solid blue; pointer-events:none; }
/* doesn't work in opera and ie */


.content { position:absolute; top:0; left:0; width:100%; height:100%; z-index:0;}
.content:hover { background:blue; }
Bell
  • 445
  • 4
  • 13
Litek
  • 4,888
  • 1
  • 24
  • 28
5

Simply: don't nest your #inner div inside. Little demo: little link. Note that I added:

html, body {
    position: relative;
}

Which is necessary in this case.

Edit: in case you insist on having it nested, a bit of JavaScript is necessary. Here's a sample:

var inn = document.getElementById("inner"), outt = document.getElementById("holder");
outt.onmouseover = function() {
   this.style.backgroundColor = "rgb(0, 162, 232)"; /*I like this color :)*/
}
outt.onmouseout = function() {
   this.style.backgroundColor = "orange";
}
inn.onmouseover = function(ev) {
   ev.stopPropagation();
}

(This would be shorter if written using jQuery, but the idea is the same).

Here's a demo: little link.

Chris
  • 26,544
  • 5
  • 58
  • 71
  • I don't think it's necessary. – BoltClock Sep 29 '12 at 12:16
  • @BoltClock Well, I've tried without it; apparently `html` and `body` don't get `position: relative;` by default. – Chris Sep 29 '12 at 12:17
  • 1
    The element needs to be nested in it's parent – CupOfTea696 Sep 29 '12 at 12:18
  • @CupOfTea696 Why, precisely? What are you trying to achieve? – Chris Sep 29 '12 at 12:19
  • @Abody97: Now that is bizarre. They don't get it by default, but an absolutely-positioned element should still be relative to the viewport if none of its ancestors are relative. – BoltClock Sep 29 '12 at 12:20
  • @BoltClock `html` and `body` don't always expand to fill the viewport, you know. In this case, they're only becoming as large as needed to fit `#holder`. – Chris Sep 29 '12 at 12:22
  • @Abody97: Oh, I get it - the top/left/bottom/right offsets are missing, which may be the issue. I've never understood how `auto` works for those properties. – BoltClock Sep 29 '12 at 12:27
  • Yea I know I could solve this with jQuery but I was actually wondering if there's a CSS only solution. – CupOfTea696 Sep 29 '12 at 17:06
  • 1
    @CupOfTea696 Probably not. `:hover` states in CSS are propagated -- no real way of preventing them. Although, I must point out, the snippet in my answer doesn't use jQuery :) – Chris Sep 29 '12 at 17:42
  • 1
    Well, you could add a transparent element over the child, but that feels a bit dirty to me. – Ana Sep 29 '12 at 19:43
0

You need to use a bit of JavaScript to stop the event from bubbling. Take a look at this example:

css :hover only affect top div of nest

Community
  • 1
  • 1
PRB
  • 484
  • 2
  • 5