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 book coverPro CSS3 Animation, Apress, 2013

my other blogs

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

my projects

The New DefaultsThe New Defaults — A Sass color keyword system for designers.

CSSslidyCSSslidy — an auto-generated #RWD image slider. 3.8K of JS, no JQuery.

Quad-Image Gallery

A simple transitioned display for four or more photographs

A little gallery I was inspired to pull together last night: four images arranged in a rectangle, each transitioned to a larger size on a click, with captions.

The markup uses <figure> elements inside a <div>. alt attributes have been minimized to save space:

<div id="quad">
<figure>
<img src="rose-red-wine.jpg" alt>
<figcaption>Rose Red Wine</figcaption>
</figure>
<figure>
<img src="guiness-barrels.jpg" alt>
<figcaption>Barrels of Guinness, Dublin</figcaption>
</figure>
<figure>
<img src="green-glass-bottle.jpg" alt>
<figcaption>One Green Bottle</figcaption>
</figure>
<figure>
<img src="crystal-skull-vodka.jpg" alt>
<figcaption>Crystal Skull Vodka</figcaption>
</figure>
</div>

The initial CSS ensures that the images remain side-by-side with each other at the correct aspect ratio:

div#quad {
background-color: #111; font-size: 0;
width: 50%; margin: 0 auto;
}
div#quad figure {
margin: 0; width: 50%; height: auto;
transition: 1s; display: inline-block;
position: relative;
}
div#quad figure img { width: 100%; height: auto; }

Next, we make sure that each <figure> is transformed from its far corner, relative to its overall container. Vendor prefixes have been removed for clarity:

div#quad figure:nth-child(1) { transform-origin: top left; }
div#quad figure:nth-child(2) { transform-origin: top right; }
div#quad figure:nth-child(3) { transform-origin: bottom left; }
div#quad figure:nth-child(4) { transform-origin: bottom right; }

Finally, the CSS for the presentation of the captions and the full-width elements:

div#quad figure figcaption {
margin: 0; opacity: 0;
background: rgba(0,0,0,0.3); color: #fff;
padding: .3rem; font-size: 1.2rem;
position: absolute; bottom: 0; width: 100%;
transition: 1s 1s opacity;
}
.expanded { transform: scale(2); z-index: 5;  }
div#quad figure.expanded figcaption { opacity: 1; }
div.full figure:not(.expanded) { pointer-events: none; }
div#quad figure:hover { cursor: pointer; z-index: 4; }

These styles are perhaps best understood in the context of the JavaScript that is applied at the end of the document:

<script>
var quadimages = document.querySelectorAll("#quad figure");
for(i=0; i<quadimages.length; i++) {
quadimages[i].addEventListener( 'click',  function(){ this.classList.toggle("expanded");
quad.classList.toggle("full") }
);
}
</script>

When the user clicks or touches small image, it is expanded to a full-width presentation with an applied class. The z-index associated with this state ensures that the image is always on top of the others, further guaranteed by removing pointer events from the other images at the same time.

The only condition is that all the images must be exactly the same size; in theory, this could be applied to a system of six or more images with appropriate transform-origin settings, so long as their aspect ratios matched.

Images by Pete Slater, Christina Ann VanMeter, Jen Scheer and  Shadi Samawi, licensed under Creative Commons. Play with the code for this gallery 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.