Copy hi@ste․digital
Posted on

Enhancing your Image Thumb Galleries using CSS3 Transitions and Transforms

We’re going to look at using progressive enhancement techniques to improve our user’s experience, in this case, with image galleries. These enhancements aren’t essential to the functionality of our galleries, but they do show that we care about our users, offering them the best experience we can in their browser of choice.

The techniques use only CSS, so are very easy to implement and very lightweight when squared against some JavaScript that achieves the same outcome.

Try not to get carried away with these techniques; remember that they’re meant to enhance the experience for those with capable browsers, not punish those who perhaps aren’t as aware of the software they’re using.

The examples we’ll be discussing are in no way lightbox alternatives or have anywhere near the same capabilities, but they do provide some middle ground by subtly enhancing our image thumb galleries, much like the way Google Images provides a further taster by slightly enlarging their images when they’re hovered over.

Go see the demo to see all the techniques in practice and to get an idea of all we’ll be talking about…

Responsive Framework

This isn’t the main aspect of our discussion, but we’re going to quickly run through building an image thumb gallery using percentage values and other responsive techniques to ensure it looks good on all devices.

First of all, we need a containing div. Inside this element, we have our images, which I’m going to put inside an unordered list (<ul>); the <li>s that will wrap our images will come in handy when making these images responsive.

So here’s our markup for the gallery…

<div>
    <ul>
        <li><img src="1.jpg" alt=""></li>
        <li><img src="2.jpg" alt=""></li>
        <li><img src="3.jpg" alt=""></li>
        <li><img src="4.jpg" alt=""></li>
        <li><img src="5.jpg" alt=""></li>
        <li><img src="6.jpg" alt=""></li>
    </ul>
</div>

Easy, simple and clean markup. Now for some simple CSS to match.

Seeing as our gallery is for thumbnail images, we’ll give our containing <div 30% of the page width. Now, we have 6 images to accommodate – let’s go for 2 rows of 3. We’re going to give each containing <li> 30% of the containing <div>.

So 30% multiplied by 3 list items (per row) equals 90% (doesn’t take a genius), leaving us 10% for our margins. A row of 3 images leaves us with 4 gutters to fill between the containing <div> and between each of the images. 10% divided by 4 is 2.5%, so that is the width of our margins. Simple!

div {
    width:30%;
    margin:0 auto; /* Centres page */
}

ul {
    width:100%;
    padding-bottom:2.5%;
    background:#ccc;
    float:left;
}

ul li {
    width:30%;
    margin:2.5% 0 0 2.5%;
    float:left;
    position:relative; /* Needed for z-indexing later */
}
Grid for our gallery

Finally, we need to ensure our images fit inside of the <li>s. To do this we simply give our <img> elements a max-width value of 100%, ensuring that our images fill the <li>s and don’t overflow.

ul li img {
    max-width:100%;
    border:2px solid #eee;
    box-sizing:border-box; /* Don't forget vendor prefixes! */
}

You can see above that we’ve also used the border-box technique, which basically alters the laws of the box model and allows us to use pixel based border widths, without adding any more width/height to our images. So instead of the border being in addition to the image’s width/height, it is applied within the image’s width/height.

If you were actually going to create a gallery like this in the real world, you would be wise to use media queries to adjust the width of the containing <div> at different viewport sizes, as obviously 30% of a mobile device viewport would result in a tiny, barely usable thumb gallery.

Basic Hover Effects using Transforms and Transitions

We’re going to start with a simple enlarge on hover effect as you can see in Gallery One from our demo.

Right, let’s kick off by giving our thumbs an opacity value of 0.5, so that on hover we can bring it to full colour and emphasise the hover effect. So, we know that on hover we want our thumb to get bigger and strengthen in colour, but we need to add the transition values to our thumb in order for the state change to appear animated.

Our <li> now has the following CSS rules (assuming all of the general rules we defined above are still in place as well).

.gal-1 li {
    transition:all 0.6s ease; /* Remember vendor prefixes! */
    opacity:0.5;
}

The above rules simply say; make the element 50% transparent and transition any state changes for 0.6 seconds. Now we need to determine our CSS rules for the :hover state…

.gal-1 li {
    transition:all 0.6s ease; /* Remember vendor prefixes! */
    opacity:0.5;
}

.gal-1 li:hover {
    transform:scale(1.4); /* Remember vendor prefixes! */
    opacity:1;
    box-shadow:5px 3px 5px rgba(0, 0, 0, 0.3);
    z-index:2;
}

As previously discussed, we’ve made the image fully opaque and we’ve used the CSS3 transform property to make the thumb 1.4 times bigger. The beauty of the scale transform property is that it ignores everything around it and simply enlarges from its centre without effecting the surrounding layout.

I’ve also added a subtle shadow to the image to strengthen the illusion that the image is hovering above the others. And finally, I’ve given the hovered element a z-index value to ensure that the currently hovered image appears above all of the other images.

These extremely simple CSS rules give us a lovely, smooth zoom functionality on our thumb images. As I see it, the idea is still to utilise some kind of lightbox plugin to view the full image and complete the gallery experience, but these techniques go a long way to enhancing our user experience by providing an additional taster for our thumbs.

Thumb scale up

Using Rotate

There’s more to the transform property than scale; a particularly good one when combined with transitions is rotate. I’m going to make a very slight addition to the code we produced above to create a rather different transition.

.gal-2 li:hover {
    transform:scale(1.4) rotate(360deg); /* Remember vendor prefixes! */
    opacity:1;
    box-shadow:5px 3px 5px rgba(0, 0, 0, 0.3);
    z-index:2;
}

The change has been made to our rules on the :hover state. Spot the difference? All we’ve done is add another set of values to the transform property – in this case, we’ve ordered the thumb to not only scale up on hover, but to rotate 360 degrees as well, creating a more exciting transition.

Here’s the thumbnail image in mid transition.

Thumb rotate

Scattered Thumbs

The next example is a little more tedious depending on how many thumb images you have.

Scattered thumbs

I’ve scattered the thumb images by targeting each of them individually using the nth-of-type selector and then using the transform:rotate() technique to position each of the images at a different angle. Finally, I’ve introduced yet another variation of the transform property, called translate, which quite simply moves the element from one position to another. I used this to make the thumbs overlap each other slightly.

.gal-3 li:nth-of-type(2) { transform:rotate(-10deg) translate(0, 10px); }

.gal-3 li:nth-of-type(3) { transform:rotate(10deg) translate(0, 20px); }

.gal-3 li:nth-of-type(4) { transform:rotate(-40deg) translate(20px, -10px); }

/* etc. */

On the :hover state, I simply scaled the thumbnails up again and straightened out any angles.

Scattered thumb hover

Triggering Transitions on Click

The last couple of galleries in our demo employ similar effects to the ones above, only these transitions are triggered when the thumb is clicked on rather than hovered over. For a detailed explanation into how you can trigger a CSS transition on click, you may want to read this article I wrote on the matter. But Basically, we use the :target pseudo-selector.

To give you a basic understanding, the CSS rules under #one:target will only be applied if #one is at the end of the URL in the addres bar. In short, if a link to #one has been clicked, the CSS rules under #one:target will be applied. Simple.

To make this work properly, we need to modify our gallery markup…

<h2 id="gal-five">Gallery Five <span>Enlarge on Click</span></h2>
<ul class="gal-5">
    <li id="one">
        <a class="close" href="#gal-five">Close</a>
        <a href="#one"><img src="1.jpg" alt=""></a>
    </li>
    <li id="two">
        <a class="close" href="#gal-five">Close</a>
        <a href="#two"><img src="2.jpg" alt=""></a>
    </li>
    <li id="three">
        <a class="close" href="#gal-five">Close</a>
        <a href="#three"><img src="3.jpg" alt=""></a>
    </li>
    <li id="four">
        <a class="close" href="#gal-five">Close</a>
        <a href="#four"><img src="4.jpg" alt=""></a>
    </li>
    <li id="five">
        <a class="close" href="#gal-five">Close</a>
        <a href="#five"><img src="5.jpg" alt=""></a>
    </li>
    <li id="six">
        <a class="close" href="#gal-five">Close</a>
        <a href="#six"><img src="6.jpg" alt=""></a>
    </li>
</ul>

What have we done here then? Well, we’ve added an id to each <li>, we’ve wrapped our images in <a> tags which link to the corresponding <li> id. Lastly, we’ve added another link which links to the galleries <h2> id, allowing the user to escape once a thumb has been clicked on.

The markup modification is the most difficult bit about this technique really, so carry on reading…

Now we simply scale up the thumb when it’s being targeted (clicked on).

.gal-5 li:target {
    transform:scale(2.2);
    z-index:2;
    opacity:1;
}

.gal-5 li:target img {
    box-shadow:5px 3px 5px rgba(0, 0, 0, 0.3);
}

.gal-5 .close {
    display:none;
    /* other presentational styles */
}

.gal-5 li:target .close {
    display:inline;
}

After scaling the currently targeted <li>, we add the box-shadow property to the img within the currently targeted <li> and we ensure that all of the <a> tags with a class of .close are hidden unless they are within the currently targeted <li>.

This method is nice when it works, but it has its limitations; namely the page jumping to the top of targeted element. I would imagine you will very rarely find a practical use for this, but if you do, use cautiously.

Thumb scaled up when targeted

Transitioning 3D Transforms on Click

Our final gallery also triggers the transitions by clicking on the thumbs rather than hovering over them. We use all of the same techniques as we just used above, but with one small addition; yes, another transform value.

This one is just like the rotate transform value we discussed above, but with one small addition. This value is either rotateX, rotateY or rotateZ, which allow the element to rotate as if in a 3D environment. So rather than simply spinning left or right, this allows us to flip our images forwards or backwards or horizontally.

Now, before you start raging about how it doesn’t work for you, bear in mind that 3D transforms have limited support at the moment and are best viewed in the latest versions of Chrome and Safari, although Firefox 10 appears to support them now, if not perfectly.

So here’s the small addition we’ve made to our CSS…

.gal-6 li:target {
    transform:scale(2.2) rotateY(360deg);
    z-index:2;
    opacity:1;
}

We’ve simply added rotateY to our transform property, telling it to rotate 360 degrees towards us.

Here’s the bottom right thumb in mid 3D rotation:

Thumb mid-3D transform

Summing Up

As long as you remember a few key points, you can go ahead and use these techniques right now, without any worry.

  • Remember that you’re using these techniques to enhance your user’s experience in capable browsers – they’re not to be relied upon for functionality.
  • Test in all major browsers – if you’re doing things properly, your gallery should look perfectly acceptable in IE 7 and friends.
  • Remember your browser prefixes (-webkit-, -moz-, -o-, -ms-) and throw in the un-prefixed property to make it future proof.
  • Be subtle – crazy, gimmicky effects belong in the 90’s. Be elegant and delicate with the transforms & transitions you’re applying.

If you can think of any more cool transitions for thumb galleries, I’d love to see them in the comments section. And if you enjoyed this post, please share, tweet etc.!