Cross fading images

Commonly used as part of image galleries, or to show detail on products. This has traditionally been done in javascript by iterating over the opacity - using CSS transitions makes this very easy to add to your site.

Demo 1 - One image to another, on hover

Plan

Put one image on top of the other

Change the opacity of the top image on hover

Demo

Code

First up, the HTML markup. Without CSS enabled, you just get two images. Remember to add alt text for production use.

Demo 2 - One image to another, when a button is pressed (transitions)

Plan

Same as before, but instead of using the :hover pseudo class, we are going to use javascript to add a toggle a class. I'm using jQuery here because it's easy to understand, though you could just use plain old JS.

Demo

Click me to toggle

Code

First up, the HTML markup. Again, with no CSS enabled, you just get two images.

Demo 3 - One image to another with a timer (CSS animations)

Plan

You could implement this by using Javascript to toggle classes with a delay - that would allow older browsers to still have the images change. As we are looking forward though, we'll use CSS keyframes.

Start with two images absolutely positioned on top of each other.

Use CSS keyframes to define two states, one with top image transparent, one with it opaque.

Set the animations number of iterations to infinite.

Demo

Each image is visible for 9 seconds before fading to the other one.

Code

Everything's the same as Demo 1, but I've added this to the CSS and removed the hover selector

To make sense of that, I've defined 4 keyframes, specified that whatever has this animation attached will be opaque for the first 45%, then transparent for the last 45%. The animation will repeat forever, will last 10 seconds, and will run forward then backwards. In other words, image 1 will be visible for 4.5 seconds, followed by a 1 second fade, followed by 4.5 seconds of image 2 being visible. Then it will reverse, meaning that image 1 and 2 will both be visible for 9 (4.5 x 2) seconds each time.

Demo with multiple images

Staggering the animations can result in a multiple image fader.

This time I've created an animation that goes from 0 to 1 opacity, then staggered the animations so only one is visible at once.

Thanks to Pafson's comment, this is finally working as expected! He proposes the following algorithm to determine the percentages and timings:

For "n" images You must define:
a=presentation time for one image
b=duration for cross fading
Total animation-duration is of course t=(a+b)*n

Pretty cool - this can easily be extended by simply changing the background-image property with JS, and makes things much much simpler. I'm not sure if this behaviour is part of the spec or not, and I haven't seen support anywhere other than in the afore mentioned browsers.