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.

CSS 3D Image Flip Gallery With Dynamic Shadows

Dealing with diversified screens by using depth

My recent book Pro CSS3 Animation walked the reader through a simple version of a 3D flip image gallery. After publication, I wanted to take it further: thus, this article.

The UI challenge addressed here is the same focused on in many of my other CSS 3D works, such as the Origami UI: we live in a world of increasingly diversified screens, with smaller sizes rapidly becoming the norm. That demands a reconsideration of space: rather than placing captions below photographs, we might want to place them behind the image, to be revealed with a mouseover or tap action.

Creating The Basic Gallery

The markup for the image flip gallery couldn’t be much simpler:

<div class="flip-3d">
<figure>
<img src="yacht.jpg" alt="">
<figcaption>Yacht</figcaption>
</figure>
</div>
<div class="flip-3d">
<figure>
<img src="bee.jpg" alt="">
<figcaption>Bee</figcaption>
</figure>
</div>
<div class="flip-3d">
<figure>
<img src="queenstown.jpg" alt="">
<figcaption>Queens-town</figcaption>
</figure>
</div>

Note the outer divfor each figure, which will be used to create a 3D context for the gallery content.

To gain the 3D effect shown in the example, we need to do three things:

  • Make each figcaption cover the same area as the responsive image it describes.
  • Reverse that caption, placing it on the other side of the image.
  • Create a dropshadow that will move with the image, without adding any extra markup.

The Initial CSS

First, the basics: we need to manipulate the figure elements in 3D space. We achieve that by placing a perspective property on the figure’s common parent element:

div.flip-3d {
perspective: 1200px; width: 30%; float: left;
}

(Note that the CSS code is shown without any vendor prefixes in order to save space and preserve clarity).

Next, place the scalable figure elements beside each other with float and make the images within them responsive. To keep the transition of the figure elements as efficient as possible, we define in advance that we will only be tracking the element’s transformation. We also add the frequently-forgotten transform-style property, which will come in handy later.

div.flip-3d figure {
position: relative;
transform-style: preserve-3d;
transition: 1s transform;
font-size: 1.6rem;
}
div.flip-3d figure img {
width: 100%; height: auto;
}

(I’ve added an @media query to the code to simplify the gallery on smaller displays and narrowed browser windows, which is not shown here).

Positioning The Captions

The captions are placed perfectly on top of the images by using position: absolute (possible only because the figure elements are position: relative). Using half a turn (i.e. a 180° rotation) and a tiny translate value places the captions “behind” the images, so long as the transform-style property is applied correctly to the figure element. (You might want to take a look at what happens when you remove the property).

div.flip-3d figure figcaption {
position: absolute;
width: 100%; height: 100%; top: 0;
transform: rotateY(.5turn) translateZ(1px);
background: rgba(255,255,255,0.9);
text-align: center;
padding-top: 45%;
opacity: 0.6;
transition: 1s .5s opacity;
}

The text is placed in the center of the caption using a small cheat, and provided with a white background that is half-transparent. It’s completely possible to create a completely opaque figcaption, turning the image into a 3d postcard, but I prefer the visual effect of fading in the background. Note that this fade-in will be delayed by a half second so that it starts halfway through the rotation of the figure, which we have already set to last one second.

Setting The Rotations

Now that the gallery has been set up, creating the animations is simplicity itself:

div.flip-3d:hover figure { transform: rotateY(.5turn); }
div.flip-3d:hover figure figcaption { opacity: 1; }

Adding The Shadows

I was intrigued by the possibility of adding shadows below the images, a goal that was complicated by three issues:

  • The shadows should be created without adding any extra markup;
  • They had to be wide and thin: in other words, not the actual size or shape of the image – eliminating box-shadow and drop-shadow.
  • The shadows had to rotate in their own plane while moving with the image.

The solution I came up with was to use generated content filled with a radial gradient, creating the impression of a shadow “linked” to its originating element:

div.flip-3d figure:after {
content: " "; display: block;
height: 8vw; width: 100%;
transform: rotateX(90deg);
background-image: radial-gradient(ellipse closest-side, rgba(0, 0, 0, 0.05) 0%, rgba(0, 0, 0, 0) 100%); 
}

It’s probably easiest to see the final effect in an illustration from a different angle:

Illustration of flip image with projected shadow

That's it! I hope that this might provide a kernel of inspiration for your own uses of CSS 3D.

Photos by Cuba Gallery Want to learn more? Experiment with this code on CodePen

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.