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.

A Visual Database Gallery In Pure CSS

css / galleries

Estimated reading time: 2 minutes, 48 seconds

This article was inspired by one of my continuing education students, who delivered a final project with the effect you see above. His version used , but I realized the same result could be achieved in pure CSS.

This effect is best suited to a group of two dozen items or less. The goal is to filter the items by type, just as a true database would, only visually. In the example above, I’ve used travel photographs by Trey Radcliff.

The gallery images could be organized in almost any way you wish: I’ve contained the photographs in a figure element, but an unordered list or div could work equally well. Each image receives a class that identifies it as being a member of a particular set. As the class is only used as a CSS reference, and not as an actual style: an HTML5 data attribute could be equally effective.

The interesting part of the code lies immediately above the images. HTML5 allows to be placed anywhere, so we can add a series of radio buttons with matching <label> tags immediately above the <img> elements. The for attribute on each <label> will turn the associated radio button with a matching id value on and off; as the buttons all share the same name value, activation of one button will turn the others off.

<input type="radio" name="zoom" id="france"><label for="france">France</label>
<input type="radio" name="zoom" id="japan"><label for="japan">Japan</label>
<input type="radio" name="zoom" id="us"><label for="us">United States</label>
<figure id="zoom-gallery">
<img src="central-park-in-fall.jpg" alt="Central Park In Fall" class="us">
<img src="kyoto-bamboo-walk.jpg" alt="Kyoto bamboo walk" class="japan">
<img src="kyoto-forest-walk.jpg" alt="Kyoto forest walk" class="japan">
<img src="paris-reflected.jpg" alt="Paris reflected" class="france">
<img src="paris-skyline.jpg" alt="Paris skyline" class="france">
<img src="yosemite-clouds.jpg"" alt="Yosemite clouds" class="us">

Now for the CSS. We’ll start with a basic setup:

figure#zoom-gallery { margin: 0; padding: 0; }
figure#zoom-gallery img {  width: 40%; max-width: 300px; margin: 3%; transition: .7s all ease-in-out; } 
label { color: #fff; font-family: Futura, Arial, sans-serif; padding: 1em; }

(I’ve removed vendor prefixes from the code to keep it clean.)

Starting with a variation of the :checked CSS I have talked about previously, we add a sibling selector to zoom images in a particular set. I’ll show one example, for the photographs taken in Japan:

input#japan:checked ~ figure img.japan { transform: scale(1.1); }

At the same time, we want to diminish any images in the gallery that are not in that particular set. Appropriately enough, we use the :not selector. Again, for the photographs from taken fro Japan:

input#japan:checked ~ figure img:not(.japan) { transform: scale(0.9); opacity: 0.6; }

Optionally, you can hide the radio buttons by setting them to display: none, leveraging the of the label elements to allow the :checked declarations to operate regardless. If you add this, it makes sense to place a :hover effect on the labels to make it clear that they act as links:

input[type="radio"] { display: none; }
label:hover { cursor: pointer; }

While there are many possible improvements that could be made – I’ve added an animated box-shadow to the image elements – that’s essentially it. The only downside to this approach versus a JavaScript solution is that it does not scale, but that’s not an issue when the number of elements is small and unchanging. Play with the code behind this gallery 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.