a css3 image gallery

Last week css3 3d-transform finally landed in the latest version of Firefox, almost simultaneously Microsoft announced similar support for IE10. Add existing webkit support and that's about all the cues I needed for some quick css3 3d-transform experimentation. The results were surprisingly positive, and so I whipped up a small demo to illustrate the ease of building a rather over-animated image gallery.

the basics

The idea is to create a ring of thumbnails with an open area in the middle. Click on one thumbnail and the image will expand to the middle of the ring, popping up in full size and leaving a hole where the original thumbnail was. To get a better of idea what I'm talking about:

Is it css3 only? Nopes, we'll be using a little javascript to make up for some bugs (or is it intended behavior after all?) in webkit. Sadly webkit does not register :focus on links. You can counter this by adding a tabindex to the links, but even then none of the animations are initiated. So instead of going the css3-only way, we'll be using a tiny javascript to register the clicks and set/remove a single class where appropriate.

the html

<section class="gallery"> <ul> <li><a href="#"><img src="..." /></a></li> ... </ul> </section>

Nothing fancy going on here, just a simple unordered list, wrapped in a section. Note that I did already add the anchor tags for future support, for now they're pretty much useless. You could add :focus support for FF, but that would make the javascript a bit more complex.

css

.gallery {height:600px; width:800px; position:relative;} .gallery a {height:75px; width:75px; overflow:hidden; position:absolute; display:block} .gallery a.flip {height:322px; width:572px; left:112px !important; top:140px !important;}

The toughest part of the whole concept is positioning the thumbnails. There are a few ways to do this (nth-of-type selector or separate classes for each image), for this little demo I chose to just add the css inline. This has one big drawback though, since we need to override these style I need !important declarations in my css. I definitely wouldn't recommend doing this in a live project, but for demo purposes it's (kinda) okay.

The rest is pretty straight-forward. We give the gallery wrapper a fixed dimension and use absolute positioning to put the thumbnails where they belong. When a thumbnail is clicked we add the .flip class and position the image in the center of the gallery.

the javascript

$(".gallery ul li a").click(function () { $(".gallery ul li a").removeClass("flip"); $(this).toggleClass("flip"); return false; });

A very simple piece of jQuery code adding and removing the flip class when needed. I guess not much additional explanation is needed here.

the magic

.gallery li {perspective:500px;} .gallery a {transform-style:preserve-3d; transition:all 0.75s linear;} .gallery a.flip {transform: rotateY(180deg);}

Both perspective and transform-style properties are not necessary if you don't want the 3d-transforms, I've added a 3d-rotation just for fun (and testing purposes). The real magic happens with the transition property though. The transition property will animate all properties when an element changes states (in other words, when the .flip class is added). All the computing from original state to end state is done by css, there is nothing more to worry about, no javascript needed to calculate positions.

The rotateY transform is just a little test and can be removed, but it does show the relative smoothness of the animation, even when more complex content is inside an element (it tested it with video running inside and the animation was still pretty smooth).

Two important things to remember: add vendor prefixes where necessary. So far all browsers need vendor prefixes for this to work, so go crazy with all your -moz and -webkit and -ms prefixes. Secondly, use animation sparingly. Don't just use it because "you can" and you think "it's cool", you'll just come off as tacky (just look at this demo, as a user I'd never want to see this on an actual site).

keyboard access and degradation

With the anchors around the images you're also assured of keyboard access, though you'll need an extra activation (enter) to actually initiate the image switch. If we'd have used the :focus selector we could've just tabbed through the different images, seeing them pop up one by one. Something for the future, I guess, when webkit is getting its shit together.

Browsers that don't support the css3 transforms get a similar experience, only without the animation. Functional support goes all the way back to ie6, so that's pretty cool.

demo conclusion

Whipping up the code for this demo took me about 10 minutes. It's not a very practical example (I wouldn't use this on my own site), but it does illustrate how easy it is to implement certain animations using css3 (and the transform:all property in particular). The future is looking a bit brighter all of a sudden.