turtlefeet turtlefeet - 3 months ago 8
CSS Question

CSS Image Opacity Fade Transitions with multiple elements (class)

Reference: http://www.sanandreasradio.com

I have a bunch of images as buttons, and they currently have an opacity change on:hover. This is faded using CSS transitions (I only have it set up for webkit browsers for testing purposes). When the page first loads, everything works as expected, you can hover over an image and it's opacity gradually increases, and when it looses focus vice versa.

When I click on an image I call a function (below) that sets the opacity of all of the image-buttons (class .station-button) opacity back to normal, then increases the opacity of the selected button to 1.0 (100%). Once that happens, the hover effect for other buttons no longer works (it also doesn't work for the selected button for some reason). The transition still works when clicking another button, but hover effects just stop working entirely.

The way it would be working (as of right now, since it doesn't take into consideration the current button which is at opacity 1.0), is that ANY button I am hovering over should have its opacity gradually changed to 0.6, EVEN the selected one (which I also need to fix in some way).

I have been staring at this for a long time without finding a solution.

How do I go about doing the totally fixed version, where un-selected buttons (opacity !=1.0) will fade to opacity 0.6 on:hover, and fade to opacity 1.0 on:click, and the currently selected will be unaffected by on:hover?

Here is the specific css and js.

CSS:

.station-button {
opacity:0.3;
cursor:pointer;
width:120px;
height:120px;
-webkit-transition:opacity .3s;
-webkit-transition-timing-function:ease;
}
.station-button:hover {
opacity:0.6;
}


JS:

function changestation(stationid) {
mystation = document.getElementById(stationid);
allofclass = document.getElementsByClassName("station-button");
for (i = 0; i < allofclass.length; i++) allofclass[i].style.opacity = 0.3;
mystation.style.opacity = 1.0;
currentstation = stationid;
loadnext();
}

Answer

You're forcing the opacity in the javascript (as a style attribute of the img) which is overriding the hover state.

Rather than forcing the opacity in the javascript, I'd use class names and just add or remove them as needed, letting the CSS sort out the opacities:

function changestation(stationid) {
    mystation = document.getElementById(stationid);
    allofclass = document.getElementsByClassName("station-button");
    for (i = 0; i < allofclass.length; i++) {
        allofclass[i].classList.remove('active');
    }
    mystation.classList.add('active');
    currentstation = stationid;
    loadnext();
}

and

.station-button.active {
    opacity: 1;
}

.station-button:hover {
    opacity:0.6;
}

Here's a JSfiddle with the code changes above.

Note that because you're hovering on the active one when you select it, it will only fade to 0.6 opacity, and then fade into 1.0 when you unhover it.

If this is a problem, you could add an extra class initially that forces the 1.0 opacity on selection, then set up a js listener to remove the class the first time it's unhovered.

Also, my version uses the HTML5 classList API so not great support: http://caniuse.com/classlist. It will be pretty easy to switch it over to className though for better browser support.