Easily Turn Your Images Into Polaroids with CSS3 by Mark

Yesterday, Jon and I were going back and forth about what to blog about next. Love of CSS and doing something cool with it is kind of our thing and we quickly jumped on a brand new idea: polaroid style images with just CSS. Holy super awesome, Batman!

With our end goal in mind (polaroid style images), we needed to set a few ground rules:

  1. Has to work on a grid of linked images
  2. Images must be randomly rotated like a pile of images you're sifting through
  3. No actual text should be used on the images (only title and alt attributes)
  4. Has to be done with just CSS (no javascript)

After establishing those requirements, we got down to business. Here's a quick rundown of how we did it. (Not big on reading? Jump right to the demo.)

Starting with the Images

We get underway by first coding up our grid of images. We used an unordered list with each image linked to our Flickr account as the baseline for everything. This would allow us to echo the title text of the anchor while creating a clickable set of images.

Once we laid the groundwork, we moved on to getting the title attribute's content to show. That was difficult at first—we didn't realize the img element wasn't fully supported for this—but we quickly got it working with the anchor.

Using :after to Create Content

If you were to look at our demo, and then at the source code, you might be a little surprised. We're not showing any actual text in our HTML. Instead, we're using a CSS2.1 pseduo-selector, :after, to get the job done. Here's a look at the CSS:

  1. ul.polaroids a:after {
  2. content: attr(title);
  3. }

By using the :after, we can add a rule to our CSS that gets the anchor tag's title attribute and echoes the content immediately following the img. You'll note that despite the selector saying "after," it actually means "after the actual content of this element," thus showing the title text withing the anchor and after the image.

And now comes the fun part of rotating our images and applying some badass styles for impact and cool-factor.

Randomly Rotate the Images

With some help from our browser-specific CSS3 properties, we can "randomly" rotate our images. To do it, we first set a default angle at which to rotate our images. From there, we apply additional rules with the :nth-child pseudo-selector to give the feeling of random.

Here's the CSS to do it:

  1. /* By default, we tilt all our images -2 degrees */
  2. ul.polaroids a {
  3. -webkit-transform: rotate(-2deg);
  4. -moz-transform: rotate(-2deg);
  5. }
  6.  
  7. /* Rotate all even images 2 degrees */
  8. ul.polaroids li:nth-child(even) a {
  9. -webkit-transform: rotate(2deg);
  10. -moz-transform: rotate(2deg);
  11. }
  12.  
  13. /* Don't rotate every third image, but offset its position */
  14. ul.polaroids li:nth-child(3n) a {
  15. -webkit-transform: none;
  16. -moz-transform: none;
  17. position: relative;
  18. top: -5px;
  19. }
  20.  
  21. /* Rotate every fifth image by 5 degrees and offset it */
  22. ul.polaroids li:nth-child(5n) a {
  23. -webkit-transform: rotate(5deg);
  24. -moz-transform: rotate(5deg);
  25. position: relative;
  26. right: 5px;
  27. }
  28.  
  29. /* Keep default rotate for every eighth, but offset it */
  30. ul.polaroids li:nth-child(8n) a {
  31. position: relative;
  32. top: 8px;
  33. right: 5px;
  34. }
  35.  
  36. /* Keep default rotate for every eleventh, but offset it */
  37. ul.polaroids li:nth-child(11n) a {
  38. position: relative;
  39. top: 3px;
  40. left: -5px;
  41. }

In the above code, we rotate all our images 2 degrees and then go back through to programatically rotate more to add variety. Here's how it looks:

The rotating above breaks down like so:

  • Every image is rotated -2 degrees by default
  • All even images are rotated 2 degrees
  • Every fifth image is rotated 5 degrees and moved right 5px
  • Every eighth image keeps the default rotation (-2 degrees) and is offset 8px from the top, 5px from the right
  • And every eleventh image keeps the default rotation but is offset 3px from the top and -5px from the left

Now, in a group of 12 images, they appear to be randomly rotated and positioned. Pretty slick, huh? Now we move onto the final details of visual aesthetic.

Final Touches

With the rotating in place, we can focus on the sex appeal of our grid of images. In addition to the basic stylistic changes, we'll add in drop shadows and a Webkit transition to smooth things out in Safari (sorry, Firefox users, but there is no support for transitions yet).

And that's a wrap! With just a bit of love from CSS, we've created some freaking sweet polaroid style images with nothing more than a list of images.

View the Demo

Be sure to read through the demo for more explanation around the CSS we've used and where to find additional information. We also included a true "pile of images" farther down the page—check it out!

View Demo »

23 Comments

  • Kevin Holesh says:

    That demo looks stunning in Safari! I had no idea this was even possible with fairly simple CSS declarations. Thanks for enlightening me :-)

    I can't wait to use this on a gallery page or something similar. It would definitely add some "progressive enrichment" to my design.

  • Mark says:

    @Kevin: It's pretty slick, huh? Safari really shines here compared to Firefox, but only because of the smooth transitions in 4.x. Let us know how it goes if you use it on your next project! Making it degrade for older browsers (read: Internet Explore) shouldn't be hard to do either.

  • Paul Lloyd says:

    Yeah, it's alright, but could be better*. Your next challenge is to adapt this code so that each image exhibits edges with a dark subtle fading effect, just like on the real things! Think you can make that happen?

    • By the way, I'm totally digging this demo, but I'm trying to keep you guys grounded ;-)
  • Mark says:

    @Paul: Hah! We accept! I already have a few ideas up my sleeve. We'll update this post when we have something worthy of your true praise :D.

  • Lewis King says:

    This is really, really awesome. First time visiting the site, but you guys are awesome! Certainly keeping an eye on you. This is going to be perfect for a new project I'm working on. Thank you so much!

  • Rich Pollock says:

    Just a head's up: the CSS in the demo is fine (obviously, as it all looks very slick), but the nth-child selectors in the article all read "nth-child(even)" when they should read "nth-child(3n)", "nth-child(5n)", etc.

    Cheers, Rich

  • Mark says:

    @Lewis: Thanks for the kind words—glad you love it!

    @Rich: Thanks for the catch. Just fixed it here on the post.

  • Martin Korych says:

    What a wicked article, I'll surely look into implementing this into our "About us" page. Thank you so much!

  • Mark says:

    @Martin: Awesome, shoot us an email or a comment when you do!

  • elliot condon says:

    Wicked tutorial!

    Gotta love css3! When is IE going to get on the bandwagon?

  • Nick Toye says:

    Not looking so hot in Safari my friend, when you hover over some of the images, the white border vanishes, so it loses it's effect.

  • Emma says:

    This looks great, is there a way to get it to automatically update from flickr?

  • beard says:

    -webkit-transform -moz-transform

    Too bad these aren't an official CSS3 spec. Not looking forward to duplicating this every time.

  • Spencer says:

    To add to Nick's comment, the #container's overflow of hidden is cutting the images off. This also causes the #tweetmeme_button to disappear. Looks great though!

  • Rob says:

    This is awesome. Was looking for a cool gallery effect for a website i am building. Shame about IE support but oh well... their loss. My only query is whether there is a better "default" font to use if the Felt Marker isn't installed?

    On a mac with font smoothing etc it looks cool, but on windows it looks pants without the Felt Marker font. Any ideas? Arial/Georgia is ok but when rotated the text looks messy.

  • Vanessa says:

    Really cool ! CSS 3 can do great things !!! :) But it doesn't work on IE 7 & IE 8 :-\

  • MYO HAN HTUN says:

    It's really cool. I like it. I am hoping all can work well in all browser in the future. :)

    Appreciate for your great post.

  • ronald says:

    This looks great, another way to display your images . . .

  • Mohammed Morsi says:

    that's pretty cool I really like it but there is one comment on that I think that the main

    that carries the images should take overflow : visible because some images at the corners are cut because the hidden property.

  • Levi Figueira says:

    <rant> So, why not use tables to display those images? </rant>

    Glad to see you guys moved on… ;) Great tutorial! Gotta love CSS3! :D

  • James says:

    Thanks for this but I have a small problem, for some reason the hover effect only works on the first image, the rest don't work.. any ideas why this might be? As far as I can tell my code is the same as your example..

  • James says:

    Thanks for this but I have a small problem, for some reason the hover effect only works on the first image, the rest don't work.. any ideas why this might be? As far as I can tell my code is the same as your example..

    If I change it to img:hover instead of a:hover, it works on all images but obviously the surrounding elements aren't scaled.. I'm stumped!

  • James says:

    Fixed the above problem by changing ul.polaroids a:hover to ul.polaroids li a:hover :)

Add your comment...

Required

Required, but not shared. Nerd's honor.

About the ZURBlog

The ZURBlog is where we discuss design interaction and strategy. We use design thinking to challenge businesses and designers to improve the products and services they create.

What's the ZURBword?

What's the ZURBword?

ZURBword.com is our thoughts on interaction design and strategy. What?

Photos on Flickr

  • 4414442457_f7273ee48b_s
  • 4415209236_3ee49cd530_s
  • 4414440971_1f5c640d96_s
  • 4414439321_8fde28bc5d_s
  • 4414438469_8311a56d16_s
  • 4415205332_38e0a25655_s
  • 4415204866_2e441bcb41_s
  • 4415203878_de626831de_s
  • 4415203204_dbda2d2052_s

Videos on YouTube

Bookmarks on Delicious

Wanna talk? Call us at (408) 341-0600.

Hmm, not a big talker. Email us to .

Still here? Great, we're hiring.

We need people with chops to join our quest
for world domination. Want a job, nerd?

What's the ZURBword?

ZURBword.com is our thoughts on interaction design and strategy. What?

Subscribe to ZURBnews

Get our monthly newsletter, ZURBnews.
Check out last month's edition »