3

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/

Shankar Cabus
  • 9,302
  • 7
  • 33
  • 43
NaOH
  • 449
  • 1
  • 10
  • 23

4 Answers4

3

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>

A.M.K
  • 16,727
  • 4
  • 32
  • 64
  • Your welcome, the only catch is that #sb-body-inner has to be the exact same height as the navigation arrows. Otherwise, you'll have spots that don't trigger the hover. – A.M.K Sep 14 '12 at 11:45
1

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);
});
BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
Nick G.
  • 1,145
  • 2
  • 10
  • 19
  • Nick, can you elaborate on how to implement this jQuery? I've got (in a – NaOH Sep 07 '12 at 15:49
  • 1
    @NaOH, I've never used the JSON input style for .css(), but a quick look at the [jQuery API](http://api.jquery.com/css/) shows that what you have should work. Try wrapping the numerical inputs in quotes, though. It shouldn't make a difference, but it wouldn't hurt to try. – Nick G. Sep 10 '12 at 20:10
  • 1
    @NaOH, my original code would never work because there were no 'hovered' elements when the DOM loaded. Instead, I've added a hover event binder to the elements in question and modified their and their sibling's behavior in the handler functions. I've run this on your website with success. – Nick G. Sep 13 '12 at 19:07
1

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.

Shankar Cabus
  • 9,302
  • 7
  • 33
  • 43
  • 1
    [Specificity is not counted in "points" like that.](http://stackoverflow.com/questions/2809024/points-in-css-specificity) – BoltClock Sep 06 '12 at 20:30
  • 1
    Cool @BoltClock , did not know that. When I learned CSS still spoke in points. And to be honest, it always worked and always will work in 99.99% of cases. =) – Shankar Cabus Sep 06 '12 at 20:33
1

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;
}
Armel Larcier
  • 15,747
  • 7
  • 68
  • 89
  • 1
    If you disable the pointer events then how can the buttons be clicked? Besides, wouldn't that instantly remove the hover state? – A.M.K Sep 13 '12 at 19:55
  • 1
    Sorry, I didn't see that it was targeting the clone navs. – A.M.K Sep 13 '12 at 20:02
  • 1
    The pointer-events are disabled for the clone buttons (the "previous" button contained in the next button's anchor? – Armel Larcier Sep 13 '12 at 20:06