10

I have a DOM structure containing several divs. Visually, some of these Divs are children of others, but in the DOM Structure they are all siblings.

I need to style the hover state of the "parent" divs even when hovering over its "child" divs.

Is there a way of doing this without Javscript? Maybe by using the current position of the divs to know they are inside of another div?


Update


The problem is the parents are actually siblings. There's only one container and let's say 8 children divs. 2 are bigger divs and the other six are shown 3 inside each bigger div. Something like:

http://jsfiddle.net/XazKw/12/

Only the parent surrounding the hovered children should change color.

I can't change the DOM structure BTW.

markitusss
  • 360
  • 1
  • 5
  • 15
  • Could you post some sample mark up, and show what you want to happen? It seems that you want to style a parent div, as you hover one of its child elements? – David Thomas Dec 20 '11 at 18:06
  • Such calculations can only be done with JavaScript. – BoltClock Dec 20 '11 at 18:06
  • 2
    there IS a sibling selector in CSS3: http://stackoverflow.com/questions/1817792/css-previous-sibling-selector This would imply that you are developing for modern versions of browsers. – Brian Hoover Dec 20 '11 at 18:06
  • @BrianHoover why not just use the adjacent sibling selector? – Wex Dec 20 '11 at 18:18
  • @Wex - because the original request was "several" siblings. Also, I wasn't aware there was an adjacent sibling selector. Google has let me down :( – Brian Hoover Dec 20 '11 at 18:23
  • @BrianHoover see http://www.w3.org/TR/CSS2/selector.html#adjacent-selectors. Regardless, using this selector would select the child element, not the parent element. – Wex Dec 20 '11 at 18:27
  • The problem is the parents are actually siblings. There's only one container and let's say 8 children divs. 2 are bigger divs and the other six are shown 3 inside each bigger div. Something like: http://jsfiddle.net/XazKw/12/ Only the parent surrounding the hovered children should chang color. – markitusss Dec 20 '11 at 21:44

5 Answers5

3

I can't think of a clean (or even a hacky) way of doing it with just CSS. Here's a Javascript method if you don't figure anything else out. Just trap mousemove on body.

function isOver( element, e ) {

    var left = element.offsetLeft,
        top = element.offsetTop,
        right = left + element.clientWidth,
        bottom = top + element.clientHeight;

    return ( e.pageX > left && e.pageX < right && e.pageY > top && e.pageY < bottom );

};

Demo: http://jsfiddle.net/ThinkingStiff/UhE2C/

HTML:

<div id="parent"></div>
<div id="overlap"></div>

CSS:

#parent {
    border: 1px solid red;
    height: 100px;
    left: 50px;
    position: relative;
    top: 50px;
    width: 100px;
}

#overlap {
    background-color: blue;
    border: 1px solid blue;
    height: 100px;
    left: 115px;
    position: absolute;
    top: 130px;
    width: 100px;
    z-index: 1;
}

Script:

document.body.addEventListener( 'mousemove', function ( event ) {

    if( isOver( document.getElementById( 'parent' ), event ) ) {
        document.getElementById( 'parent' ).innerHTML = 'is over!';        
    } else {
        document.getElementById( 'parent' ).innerHTML = '';
    };

}, false );           

function isOver( element, e ) {

    var left = element.offsetLeft,
        top = element.offsetTop,
        right = left + element.clientWidth,
        bottom = top + element.clientHeight;

    return ( e.pageX > left && e.pageX < right && e.pageY > top && e.pageY < bottom );

};
ThinkingStiff
  • 64,767
  • 30
  • 146
  • 239
2

No, you can't affect parents or previous siblings through CSS alone. Only following siblings, which doesn't help you here.

Anyone else want a :parent pseudo-class?

DanMan
  • 11,323
  • 4
  • 40
  • 61
  • What would a `:parent` pseudo-class select? The same thing as `:not(:empty)`? – BoltClock Dec 20 '11 at 23:22
  • `div p :parent` would select div elements that contain p elements, for example. It would be like a Linux command of: `cd /files/images/../` which would end up in going to the `/files` directory. – DanMan Dec 21 '11 at 09:42
0

How about surrounding all the elements with a single container, and then doing something like:

#container:hover .parent { /* Hover styles applied */ }

Like: http://jsfiddle.net/Wexcode/XazKw/

Wex
  • 15,539
  • 10
  • 64
  • 107
0

If the styling takes effect upon hover of a DOM sibling, you should just be able to use the sibling selector:

.parent:hover ~ .child { /* styling */ }
BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
Bah Bah the Lamb
  • 146
  • 1
  • 2
  • 5
0

What can't be done can (often) be faked. While the most simple solution would be to rearange the DOM and using adjacent sibling selector there is other way, that is a) more complicated b) requires a modern browser.

You can use pseudo-elements to fake a hover effect on parent. Said pseudo-element would be only visible when hovering it's parent - .child in this case:) and positioned absolutely to compensate .childs offset from .parent covering the .parent thus looking like the parent changed state.

Fiddle here.

Litek
  • 4,888
  • 1
  • 24
  • 28
  • I know he can't change the DOM. Just wanted to share my thoughts before providing a solution that doesn't change the DOM. – Litek Dec 21 '11 at 12:04