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

my books

Pro CSS3 Animation, Apress, 2013

Using SVG with CSS3 and HTML5, O'Reilly, 2017

my other blogs

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

my projects

The New Defaults — 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.

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

A neat and easy-to-achieve effect for gallery navigation

I found this effect used on YouTube’s Google+ page and decided to duplicate it in CSS3: if you’re familiar with CSS, 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 card fan.

  1. <div id=cardfan">
  2. <img src="zen.jpg" alt="Zen" title="Zen" />
  3. <img src="matera-italy.jpg" alt="Matera, Italy" title="Matera Italy" />
  4. <img src="tivoli-italy.jpg" alt="Tivoli, Italy" title="Tivoli, Italy" />
  5. </div>

(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.

  1. 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:

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

(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:

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

(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:

  1. div#cardfan:hover img:first-child {
  2. -webkit-transform: rotate(12deg);
  3. transform: rotate(12deg);
  4. }

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:

  1. div#cardfan:hover img:last-child {
  2. -webkit-transform: rotate(-12deg);
  3. transform: rotate(-12deg);
  4. }

When you move your mouse over the div, the first and last images will change, but they will move around their centres:

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 and the webkit side: you’ll have to repeat this with other vendor prefixes to cover other browsers )

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

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:

  1. -webkit-transition: all .6s linear;
  2. 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.

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.