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
Pro CSS3 Animation, Apress, 2013
Massive Head Canon
The New Defaults
CSSslidy