jaspn
jaspn

Reputation: 413

Using :hover on one div to affect the background-position of another div

I have a stack of divs all on top of one another which are set to position:absolute, all contained in a container div. What I would like to do is change the background-position of #feature_1_shade when the user hovers over #feature_1_hitbox. I have tried to achieve this by using -

#feature_1_hitbox:hover #feature_1_shade {
background-position: 0 0;
}

This doesn't work. However, it DOES work if I apply it to the container div as such:

#feature_1_container:hover #feature_1_shade {
background-position: 0 0;
}

I would almost settle for this, but I need the hitbox to be a specific size, so the :hover must be applied to my hitbox div. Is there any reason why this works for one div and not another?

Here's the markup code:

<!-- container --> <div id="feature_1_container">
<!-- shade --> <div id="feature_1_shade"></div>
<!-- text and arrow --> <div id="feature_1_text_container"><h3 id="feature_1_arrow">Memberships</h3><p id="feature_1_text">Text here text here</p></div>
<!-- image --> <div id="feature_1_graphic"></div>
<!-- hitbox --> <a href="#"><div id="feature_1_hitbox"></div></a>

</div> <!-- #feature_1_container -->

Here's the CSS:

#feature_1_container {
width: 289px;
height: 255px;
float: left;
}

#feature_1_hitbox {
width: 289px;
height: 166px;
margin: 89px 0 0 0;
position: absolute;
/* background-color: #F99; */
}

#feature_1_graphic {
width: 289px;
height: 255px;
position: absolute;
background-image: url(site_style_images/feature_1_memberships_bag.png);
}

#feature_1_text_container {
width: 289px;
margin: 100px 0 0 0;
position: absolute;
}

#feature_1_text {
margin: 0 0 0 100px;
}

#feature_1_arrow {
background-image: url(site_style_images/feature_arrows.png);
background-position: center right;
background-repeat: no-repeat;
height: 49px;
padding: 0 30px 0 100px;
margin: 0 22px 0 0;
color: #8d895c;
font-size: 22px;
line-height: 44px;
font-family: 'Quicksand', sans-serif;
font-weight: normal;
letter-spacing: -2px;
font-style: normal;
}

#feature_1_shade {
width: 289px;
height: 166px;
margin: 89px 0 0 0;
background-image: url(site_style_images/feature_1_shade.png);
background-position: 0 -166px;
position: absolute;
background-color: #CCC;
}

#feature_1_hitbox:hover #feature_1_shade {
background-position: 0 0;
}

Upvotes: 0

Views: 725

Answers (2)

Kye
Kye

Reputation: 1

The reason it doesn't work is because for CSS selectors, #container:hover #shade{} actually styles the ID #shade INSIDE the ID #container. In your markup code, #shade is nested IN #container but NOT in #hitbox. Perhaps adding another "invisible div" (opacity:0) with the exactly same size and same position as the hitbox and including the shade inside the invisible div then styling the invisible div with its hover selector might work. Example: #invisible_hitbox_hover:hover #shade{}

Upvotes: 0

Matt Coughlin
Matt Coughlin

Reputation: 18906

With the HTML source code in that order, you'll have to use JavaScript or jQuery. A CSS selector can't refer backwards to an earlier element.

If the source order was reversed, you might be able to do something like:

#feature_1_hitbox:hover ~ a #feature_1_shade

If jQuery is an option, you could add and remove a class to #feature_1_shade based on the hove state of #feature_1_hitbox:

CSS

#feature_1_shade.on {...}

jQuery

$("#feature_1_hitbox").hover(
    function(){ $('#feature_1_shade').addClass('on'); },
    function(){ $('#feature_1_shade').removeClass('on'); }
);

The JavaScript equivalent is:

var obj = document.getElementById("feature_1_hitbox");
obj.onmouseover = function(){
    document.getElementById("feature_1_shade").className = "on";
}
obj.onmouseout = function(){
    document.getElementById("feature_1_shade").className = "";
}

Note: If #feature_1_shade uses any other classes, you'll have to be careful when adding or removing a class with plain JavaScript.

Upvotes: 1

Related Questions