简体   繁体   中英

Style hover state of element when hovering over overlapping elements with CSS

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.

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 );

};

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?

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/

如果样式在DOM兄弟的悬停时生效,您应该只能使用兄弟选择器:

.parent:hover ~ .child { /* styling */ }

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 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM