Have two elements appear when their container is hovered, and then have one disappear when the other is hovered specifically?

Problem

I have two navigational elements that are set up as columns on either side of an image. You can see them in place at my website, here. Click on any image and after it loads, hover over it.

What I'm trying to accomplish is as follows:

  1. When the cursor is outside of the image, both nav buttons are set at 0% opacity.
  2. When the image is hovered in the center (not over either of the two nav buttons), both nav buttons are set at 50% opacity.
  3. When either nav button is hovered directly, it is set at 100% opacity and the other nav button is set at 0% opacity.

This isn't working at the moment. HTML is as follows:

<div id="sb-body">
    <a id="sb-nav-previous" class="sb-bignav" title="Previous" onclick="Shadowbox.previous()"></a>
    <a id="sb-nav-next" class="sb-bignav" title="Next" onclick="Shadowbox.next()"></a>
    <div id="sb-body-inner">
        <img style="position: absolute;" src="Corrosion.jpg" id="sb-player" height="405" width="609">
    </div>
</div>

And CSS is as follows:

    #sb-nav-next {
    right:0;
    background:url('../images/nav-right.png') center center no-repeat;
}

#sb-nav-previous {
    left:0;
    background:url('../images/nav-left.png') center center no-repeat;
}

#sb-body:hover .sb-bignav {
    opacity:0.5;
    -webkit-opacity:0.5;
    -moz-opacity:0.5;
}

#sb-nav-next:hover #sb-nav-previous, 
#sb-nav-previous:hover #sb-nav-next {
    opacity:0;
    -webkit-opacity:0;
    -moz-opacity:0;
}

.sb-bignav {
    cursor:pointer;
    position:absolute;
    width:200px;
    height:100%;
    top:0;
    z-index:400;
    opacity:0;
    -webkit-opacity:0;
    -moz-opacity:0;
    transition: opacity .125s ease-in;
    -webkit-transition: opacity .125s ease-in;
    -moz-transition: opacity .125s ease-in;
}

.sb-bignav:hover {
    opacity:1.0;
    -webkit-opacity:1.0;
    -moz-opacity:1.0;
}​

Demo: http://jsfiddle.net/zNkcQ/

Problem courtesy of: NaOH

Solution

This can be done using pure CSS, but, you need to move the previous and next elements past the inner body element.

Demo: http://jsfiddle.net/SO_AMK/c5Xn3/

CSS:

#sb-body-inner { 
    height: 405px; 
} 
/* This is the height of the image inside the slider.
If you do not change this line than #sb-body-inner will be about 20px tall and 
will not trigger the hover event */

#sb-body-inner:hover ~ #sb-nav-previous.sb-bignav,
#sb-body-inner:hover ~ #sb-nav-next.sb-bignav { 
    opacity: 0.5; 
}

#sb-nav-previous.sb-bignav:hover,
#sb-nav-next.sb-bignav:hover {
    opacity: 1.0;
    -webkit-opacity: 1.0;
    -moz-opacity: 1.0;
}

.sb-bignav {
    cursor: pointer;
    position: absolute;
    width: 200px;
    height: 100%;
    top: 0;
    z-index: 400;
    opacity: 0;
    -webkit-opacity: 0;
    -moz-opacity: 0;
    transition: opacity .125s ease-in;
    -webkit-transition: opacity .125s ease-in;
    -moz-transition: opacity .125s ease-in;
}

#sb-nav-next {
    right: 0;
    background: url('http://www.element17.com/images/nav-right.png') center center no-repeat;
}

#sb-nav-previous {
    left: 0;
    background: url('http://www.element17.com/images/nav-left.png') center center no-repeat;
}​

HTML:

<div id="sb-body">
    <div id="sb-body-inner">
        <img style="position: absolute;" src="http://www.element17.com/gallery/01_CONSTRUCTS/Shear.jpg" id="sb-player" height="405" width="609">
    </div>
    <a id="sb-nav-previous" class="sb-bignav" title="Previous" onclick="Shadowbox.previous()"></a>
    <a id="sb-nav-next" class="sb-bignav" title="Next" onclick="Shadowbox.next()"></a>
</div>

Solution courtesy of: A.M.K

Discussion

Well, I've exhausted all of my references for a css solution to this problem. The issue is that you'll never get the left nav overlay to become transparent because there is no way to select an element's preceding sibling. I used #sb-body .sb-bignav:hover ~ .sb-bignav { opacity: 0; } with success on getting the right nav overlay to become transparent, but that's it.

I suggest using jQuery to do this:

OLD

$('.sb-bignav:hover').siblings().css('opacity', 0);

NEW

$('.sb-bignav').hover( function(){
    var self = $(this);
    self.css('opacity', 1);
    self.siblings('.sb-bignav').css('opacity', 0);
}, function(){
    var self = $(this);
    self.css('opacity', .5);
    self.siblings('.sb-bignav').css('opacity', .5);
});
Discussion courtesy of: Nick G.

The first problem is the specificity of each selector. The more specific (more points) overrides the less specific (fewer points).

ID: 100 points

Class: 10 points

Element: 1 point

Then, this rule has 110 points:

#sb-body:hover .sb-bignav {
    opacity:0.5;
    -webkit-opacity:0.5;
    -moz-opacity:0.5;
}

Below, the rule has 10 points and is being overwritten by the previous rule with 110:

.sb-bignav:hover {
    opacity:1.0;
    -webkit-opacity:1.0;
    -moz-opacity:1.0;
}​

Try this CSS:

#sb-nav-next {
    right:0;
    background:url('http://www.element17.com/images/nav-right.png') center center no-repeat;
}

#sb-nav-previous {
    left:0;
    background:url('http://www.element17.com/images/nav-left.png') center center no-repeat;
}

#sb-body:hover .sb-bignav {
    opacity:0.5;
    -webkit-opacity:0.5;
    -moz-opacity:0.5;
}

#sb-body .sb-bignav:hover {
    opacity:1.0;
    -webkit-opacity:1.0;
    -moz-opacity:1.0;
}

.sb-bignav {
    cursor:pointer;
    position:absolute;
    width:200px;
    height:100%;
    top:0;
    z-index:400;
    opacity:0;
    -webkit-opacity:0;
    -moz-opacity:0;
    transition: opacity .125s ease-in;
    -webkit-transition: opacity .125s ease-in;
    -moz-transition: opacity .125s ease-in;
}

Demo: http://jsfiddle.net/DmAVQ/

​ The second problem is that you can not do the third item only with CSS.

"When either nav button is hovered directly, it is set at 100% opacity and the other nav button is set at 0% opacity."

You need to use JavaScript to do this.

Discussion courtesy of: Shankar Cabus

Just an idea... Maybe you could do it by placing 2 clone navs in your anchor tags... I made a fiddle: http://jsfiddle.net/zNkcQ/5/

<div id="sb-body">
    <a id="sb-nav-previous" class="sb-bignav" title="Previous" onclick="Shadowbox.previous()">               
        <span class="sb-img-next"></span>              
        <span class="sb-img-previous"></span>
    </a> 
    <a id="sb-nav-next" class="sb-bignav" title="Next" onclick="Shadowbox.next()">              
        <span class="sb-img-previous"></span>              
        <span class="sb-img-next"></span>
    </a>
    <div id="sb-body-inner">
        <img style="position: absolute;" src="Corrosion.jpg" id="sb-player" height="405" width="609">
    </div>
</div>
.sb-img-previous{
    left:0;
    pointer-events: none;
    background:url('http://www.element17.com/images/nav-left.png') center center no-repeat;
}
.sb-img-next{
    right:0;
    pointer-events: none; 
    background:url('http://www.element17.com/images/nav-right.png') center center no-repeat;
}
.sb-img-previous, .sb-img-next{
    position: fixed;
    width: 200px;
    height: 100%;
    etc...
}
#sb-nav-previous .sb-img-next,
#sb-nav-next .sb-img-previous,
#sb-nav-previous:hover .sb-img-previous,
#sb-nav-next:hover .sb-img-next{
    opacity: 0.5;
    pointer-events: none; //So each button will not be burdened by its duplicate...
}
#sb-nav-previous .sb-img-previous,
#sb-nav-next .sb-img-next,
#sb-nav-previous:hover .sb-img-next,
#sb-nav-next:hover .sb-img-previous{
    opacity: 0;
}
Discussion courtesy of: Armel Larcier

This recipe can be found in it's original form on Stack Over Flow.