I’m Dudley Storey, the author of Pro CSS3 Animation. This is my blog, where I talk about web design and development with , and . To receive more information, including news, updates, and tips, you should follow me on Twitter or add me on Google+.

web developer guide

my books

Book cover of Pro CSS3 AnimationPro CSS3 Animation, Apress, 2013

my other blogs

Massive Head Canon: Intelligent discussion of movies, books, games, and technology.

my projects

A Sass color keyword system for designers. Replaces CSS defaults with improved hues and more memorable, relevant color names.

CSSslidy: an auto-generated #RWD image slider. 3.8K of JS, no JQuery. Drop in images, add a line of CSS. Done.

tipster.ioAutomatically provides local tipping customs and percentages for services anywhere.

Florence, ItalyAncient Aqueduct, ItalyBike on a Roman Street

“Card Fan” CSS3 Gallery Reveal In Four Lines of Code

css / galleries

Estimated reading time: 4 minutes

I found this effect used on YouTube’s Google+ page and decided to duplicate it in CSS3: if you’re familiar with , and are prepared to use a little CSS3 animation, the technique is not difficult to achieve at all. (Move your mouse over the image above to see the final version).

First, the images you wish to use in the fan need to be all the same size, so that they hide each other neatly when stacked. For this example I’m using Creative Commons licensed photos from Flickr, taken by Riccardo Cuppini.

Once you have all of your images the same size, place them inside a single <div> the same width and height as the images; I’ve given this div an id of cardfan.

<div id="cardfan">
<img src="zen.jpg" alt="Zen">
<img src="matera-italy.jpg" alt="Matera, Italy">
<img src="tivoli-italy.jpg" alt="Tivoli, Italy">

(The height on the div is necessary to create space underneath it, as the photos will be positioned absolutely.) You may wish to use margin: 0 auto on the div to get it to the middle of the page.

div#cardfan { width: 300px; height: 201px; margin: 0 auto; }

As all the images have the same dimension and will be given the same appearance, they can all be styled with a single descendant selector, to create a frame and drop shadow:

div#cardfan img { width: 300px; height: 201px; border: 18px solid #ffe; box-shadow: 6px 6px 3px rgba(0, 0, 0, 0.2); }

(Note that I’m only showing final versions of CSS3 properties where applicable, in order to save space – to create full backwards browser compatibility, you should add other vendor prefixes as appropriate).

Together with the width on the div, this puts the images in a visual column. We want to stack them, so we’ll use position: absolute to do so:

div#cardfan img { width: 300px; height: 201px; border: 18px solid #ffe; box-shadow: 6px 6px 3px rgba(0, 0, 0, 0.2); position: absolute; }

(A minor point: the only downside to this is that the drop shadows applied to each image add together to create a thick, dense shadow underneath. You could get around this by applying the shadow to just one image, and then adding shadows to the other images when they animate).

Now to get the images to move. We only want to move two of the images: the one on top of the stack, and the one at the bottom. The image in the middle will be the centre of the “fan”, and doesn’t need to be animated. We can get to the first and last images by using first-child and last-child.

We want to initiate the animation by the user moving their mouse over the div, so the appropriate selector is:

div#cardfan:hover img:first-child { transform: rotate(12deg); }

There’s no animation yet, just a single “jump”. Note that the image that is transformed is the one on the bottom, since it appears first in the code, and is thus the “first child” of the div.

Let’s apply the same rotate transform, but in the opposite direction, to the last-child:

div#cardfan:hover img:last-child { transform: rotate(-12deg); }

When you move your mouse over the div, the first and last images will change, but they will move around their centres:Stacked CSS3 rotation of images with default origin

We want to change that point to be significantly below the images: think of the hands on a clock, or the hinge of a fan. We do this by giving new values to the transform-origin for our earlier declaration for all the images (again, I’ll show you just the final expected CSS spec version: you’ll have to repeat this with vendor prefixes to cover other browsers )

div#cardfan img { width: 300px; height: 201px; border: 18px solid #ffe; box-shadow: 6px 6px 3px rgba(0, 0, 0, 0.2); position: absolute; transform-origin: center 600px; }

This keeps the horizontal position of the origin point unchanged, but moves it down 600 pixels. (You may find that you’ll have to change the degree values for rotating the first and last images as a result).

Finally, we need to add animation: we don’t just want a “jump”. We’ll do so by adding a transition property to the declaration above:

transition: all .6s linear;

Because the effect is so quick, we don’t need any easing – I’ll provide an example of a more appropriate use of ease-in and out in an upcoming article.

That’s it: an animated card fan effect in effectively four lines of CSS.

Smoothing Animations In Chrome and Safari

You may see a slight “flash” or “blink” when viewing the animation in Chrome or Safari, or notice that the edges of the pictures seem a little jagged. Both issues are solved by a single trick, applied to the first and last images:

-webkit-backface-visibility: hidden;
Play with this code on CodePen.
comments powered by Disqus

This site helps millions of visitors while remaining ad-free. For less than the price of a cup of coffee, you can help pay for bandwidth and server costs while encouraging further articles.