2

OK, let's say I have a similar structure like the one following :

<div comp-id='one'>
    <div comp-id='two'>
         <div comp-id='three'>
         ...
         </div>
    </div>
</div>

All I want to do is to apply a hover effect to the child (in this case, the one with comp-id="three").


IMPORTANT NOTE : I don't want to target specifically [comp-id="three"]. I want to target any child, with no-matter-which comp-id value. In the real-world example, there may be infinite nested [comp-id]ed divs. I just need the innermost child.

What I'm trying to achieve :

  • User hovers over three, then just three is highlighted (not one and two)
  • User hovers over two, then just two is highlighted (not one - and, of course, not three)

My current CSS code :

[comp-id]:hover {
    box-shadow: inset 0 0 0 2px red;
    -webkit-box-shadow: inset 0 0 0 2px red;
    -moz-box-shadow: inset 0 0 0 2px red;
    -o-box-shadow: inset 0 0 0 2px red;
}

However, my current CSS highlights everything which is not what I want. I could think of a javascript-based solution. What about CSS?


Warning : I'm not such a guru with CSS, so this may be really simple... :-)

Dr.Kameleon
  • 22,532
  • 20
  • 115
  • 223
  • Do you have a defined depth of your divs? Then you could access them by `div div div:hover { ... }` otherwise you can select that div by js using the `.find()` selector. – DaKirsche Aug 23 '13 at 06:33
  • @DaKirsche Nope, unfortunately there's no pre-defined depth. Could you give me an example of how `.find()` could be used in this particular case? – Dr.Kameleon Aug 23 '13 at 06:34
  • 3
    Finding innermost child with jQuery: http://stackoverflow.com/questions/4188933/how-do-i-select-the-innermost-element/4189310#4189310 (in your case it would be `$('[comp-id]:not(:has([comp-id]))')`. I don't think it's possible with pure CSS when nesting depth is not pre-deterined. – pawel Aug 23 '13 at 06:41
  • Now it looks like a duplicate of http://stackoverflow.com/questions/10364511/preventing-hover-event-of-a-div-triggering-on-parent-div – pawel Aug 23 '13 at 07:10
  • yup can't find how without a bit of js : http://jsfiddle.net/techunter/U3BrT/ – TecHunter Aug 23 '13 at 07:27
  • @TecHunter Well, your code perfectly highlights on hover the child *and* the parents. However : **I just need the child**. :-) – Dr.Kameleon Aug 23 '13 at 07:29
  • @Dr.Kameleon I know! I was just providing a fiddle and stating that you need JS for that with `e.stopPropagation()` – TecHunter Aug 23 '13 at 07:31
  • @TecHunter I thought of that just after posting my comment - mea culpa! :-) – Dr.Kameleon Aug 23 '13 at 07:37
  • @Dr.Kameleon with JS: http://jsfiddle.net/techunter/U3BrT/14/ providing some tuning when mouse leave etc... – TecHunter Aug 23 '13 at 07:47
  • 1
    @TecHunter I've already managed to answer it... myself... lol. Thanks a lot, anyway! :-) – Dr.Kameleon Aug 23 '13 at 07:49

4 Answers4

2

And... well... thanks to @BMH, this is what worked :

$('[comp-id]:not(.hover)').mousemove(function(e){
    $('[comp-id]').removeClass('hover');
    e.stopPropagation();
    $(this).addClass('hover');

});
Dr.Kameleon
  • 22,532
  • 20
  • 115
  • 223
1

This is a jQuery solution:

$('[comp-id]').mousemove(function(e){
    $(this).removeClass('hover');
    $(e.target).addClass('hover'); 
}).mouseleave(function(e){
    $(this).removeClass('hover');
});

http://jsfiddle.net/sMRMz/4/

BMH
  • 4,280
  • 1
  • 18
  • 18
  • Well, If I hover over `3` then 3 is highlighted. Which is great. However, when I hover over `2`, it's not... And the same goes for `1` as well... – Dr.Kameleon Aug 23 '13 at 06:57
  • It worked like what you've asked for before additional clarification. – pawel Aug 23 '13 at 07:02
  • 1
    I've updated my answer, your requirement changed significantly after several edits. – BMH Aug 23 '13 at 07:12
  • Well, your (last) answer did *not* solve the... riddle, either. However, you've helped **immensely** towards the solution (which I'm posting right now). And thanks a lot for that! (Hence, the +1) :-) – Dr.Kameleon Aug 23 '13 at 07:35
0

Try something like this in jQuery:

CSS:

.hoverableClass:hover {
    box-shadow: inset 0 0 0 2px red;
    -webkit-box-shadow: inset 0 0 0 2px red;
    -moz-box-shadow: inset 0 0 0 2px red;
    -o-box-shadow: inset 0 0 0 2px red;
}

JS:

function deepSearch(parent){
    var b_ClassAdd = true;
    if (!parent){
        parent = $('body');
        b_ClassAdd = false;
    }

    var allDivChilds = parent.find('div[comp-id]');
    if ((!allDivChilds || allDivChilds.length == 0) && b_ClassAdd)
        parent.addClass('hoverableClass'); 
    else
        for (var i = 0; i < allDivChilds.length; i++)
            deepSearch($(allDivChilds[i]));
}

deepSearch();

This code is untested and just an idea for a solution.

DaKirsche
  • 352
  • 1
  • 14
  • 1
    `$('[comp-id]:not(:has([comp-id]))').addClass('hoverableClass')` ;) – pawel Aug 23 '13 at 06:45
  • I do understand the point of your suggestion and it definitely is interesting. However, here's an issue : let's say we mark just the innermost child as `hoverable`. Then user hovers over its parent, and what is `hoverable` is its child, not itself. So I suppose we should take the innermost child on hover? Is this doable? – Dr.Kameleon Aug 23 '13 at 06:48
  • The function marks the innermost child of each div. It will make the same than the commented code of pawel. If a div does not have another child inside which is a div with attribute comp-id is is selected (parent) and get the class hoverableClass. – DaKirsche Aug 23 '13 at 06:54
0

You can use '>' child selector for this,to stop the cascading styles

[comp-id]:hover {
    box-shadow: inset 0 0 0 2px red;
    -webkit-box-shadow: inset 0 0 0 2px red;
   -moz-box-shadow: inset 0 0 0 2px red;
    -o-box-shadow: inset 0 0 0 2px red;
}

[comp-id]:hover > *{
  box-shadow: none;
    -webkit-box-shadow: none;
   -moz-box-shadow: none;
    -o-box-shadow: none;
}
art-fan-vikram
  • 315
  • 2
  • 12