Notice: Undefined index: order_next_posts in /nas/content/live/gadgetmag/wp-content/plugins/smart-scroll-posts/smart-scroll-posts.php on line 194

Notice: Undefined index: post_link_target in /nas/content/live/gadgetmag/wp-content/plugins/smart-scroll-posts/smart-scroll-posts.php on line 195

Notice: Undefined index: posts_featured_size in /nas/content/live/gadgetmag/wp-content/plugins/smart-scroll-posts/smart-scroll-posts.php on line 196

How to create a drag-and-drop Polaroid-style image gallery

Use CSS3 and jQuery to build an interactive Polaroid photo style gallery

Flash is officially no longer the go-to option for interactive effects on a website. Of course it’s still useful for many things, but where you simply want to create an interactive carousel or slideshow effect, JavaScript is increasingly
the weapon of choice for the majority of web designers.

This is great in most cases, but the more elaborate the effects become, the more potential for slow-down as JavaScript performance creaks under the pressure. Browser vendors have been doing much to alleviate this by redeveloping their JS rendering engines, but with the advent of CSS3 web designers can now take advantage of native rendering of common effects, reducing script workload and thus improving the user experience.

In this tutorial we’re going to create a popular effect – scattered Polaroid-style photos that can be moved around on a surface. We’re aiming to make it fun to interact with the design, so the images will need to respond to input with scale, rotation and movement. We’ll use CSS3 where we can to deal with the animation, and jQuery to enable the drag-and-drop aspect, highlighting the strength of a combination approach.

The end result is a tidy little gallery that works across different browsers, with a nice level of visual panache as well as slick user interaction.

tools | tech | trends: Graphics editor (Photoshop, Illustrator or your preferred editor), HTML editor (we used Dreamweaver, but any will do)
expert: Sam Hampton-Smith

01. Create your HTML

It’s best to keep the HTML as simple as possible. Here we’re creating a straightforward unordered list to contain each Polaroid, plus a caption using a <span> tag. You could go more semantic than this using HTML5 tags if desired. Find the complete code on the disc.

  002 <html>
  003 <head>
  004 <meta http-equiv="Content-Type"     content="text/html; charset=UTF-8">
  005  <title>CSS3 Polaroid Slideshow</title>    006
  007  </head>
  008  <body>
  009  <div id="pinboard">
  010   <ul>

02. Add your images

We grabbed all of our sample pictures from Stock XCHNG ( – if you’d like to follow along with the same images, search for ‘snow’, ‘ice’ or ‘skiing’ and download the images that appeal, or better still use your own. Each has been cropped to 300px square to work well with our Polaroid shape.

03. Locate a corkboard

We’ve chosen a corkboard background for our gallery. Do a search on Google Images for ‘corkboard tile’ and select a Creative Commons image. You’ll find lots available pre-setup as a repeating background, but if you prefer you can take your image into Photoshop and create a repeating background using Filter>Other> Offset to wrap the edges around. Apply the Clone Stamp tool over the joins and go to Save for Web.

04. The basic styles

Now we’ve got most of our images ready, we can get started on creating the visual styles for our page using CSS. Most of this is the same CSS that you’ll have seen on non-CSS3 pages; we set up the background image, make the Polaroid shape using a white background and a bit of padding to get an authentic border, and position our <span> tag on the Polaroid. The full code is available on the disc.

001     body {
  002    background:            transparent url(corkboard.jpg) repeat top left;  
  003         font-family:     ‘Nothing You Could Do’, cursive;
  004     }
 006     #pinboard {
  007       width:            1000px;
  008      height:        400px;
  009      position:        relative;
  010    margin:        auto;
  011     }

05. Script your captions

By default the captions look a little too word-processor, and don’t fit the idea of a Polaroid. Navigate to Google Web Fonts ( and search for a more suitable typeface. We have opted for Nothing You Could Do which is a nice cursive font with a handwritten feel. Add the code Google supplies to the top of your page, and then set the body CSS to use the font.

001 <link rel=”stylesheet” type=”text/css”     href=”    thing+You+Could+Do” />
  003 body {
  005 background:    transparent url(corkboard.jpg)     repeat     top left;
  007 font-family:     ‘Nothing You Could Do’,     cursive;
  009 }

06. Enter CSS3…

So far we’ve got our Polaroids set up and a nice font. It’s time to add some extra visual flair to make it all look a little tidier and more refined. We’ll start by applying some drop shadow to each Polaroid. Add the code below to your CSS to get this in place; note that we’re repeating the code several times with vendor prefixes to handle the various browsers.

001  -webkit-box-shadow: 0px 0px 10px #000;
  003 -moz-box-shadow: 0px 0px 10px #000;
  005 -o-box-shadow:    0px 0px 10px #000;
  007 -ms-box-shadow: 0px 0px     10px #000;
  009     box-shadow:        0px 0px 10px #000;

07. Basic interactions

It’s time to create our basic user interaction. We want the viewer to be able to drag the Polaroids around the page and position them wherever they choose. The easiest way to achieve this is to use jQuery and jQuery UI – the user-interface plug-in for the seminal JavaScript library. Visit and configure a download to include the draggable behaviour. Add this to your page.

001 <script src=”scripts/jquery.js”></script>
  003 <script src=”scripts/jqueryui.js”></script>

08. >Add your own script

Set up a new JavaScript document and link it into your page using script tags. Make sure your script appears beneath the jQuery and jQuery UI script calls, so that both have loaded into your page. Next, add this step’s code (which can be found on the CD) to enable drag and drop for each Polaroid. Save and test!

09. Test the drag

Load your page up in your browser and test the drag functionality. You should be able to reposition the Polaroids around the page, dropping them so they overlap and pile up. This works in every major browser thanks to jQuery, but it’s all a bit sterile at the moment, so let’s add some extra effects.

10. Set a starting position

The first issue that we need to address is the starting position of the Polaroids. They’re currently all aligned vertically, which isn’t the look we’re going for. We need to randomly scatter them across the page area, and we can do this using the random function built in to JavaScript’s math object. Add the code below inside your JS document to set this up, replacing the existing draggable() code.

001         $(“#pinboard ul li”).each(function(){
  002             xpos = Math.floor(Math.        random()*920);
  003             ypos = Math.floor(Math.        random()*420);
004             $(this).delay(1000).        animate({top:ypos,left:xpos});
  005 }).draggable();

11. How it works

We’ve set up a couple of variables to hold an x position and a y position for each list item. Using the math.random() function we’ve assigned a random number to each – between 0 and 920 for x, and 0 and 420 for y. We’ve then animated the list item into this position after a delay of 1,000 milliseconds (or one second). Add the CSS code below to position the list item in the centre by default, then once again test in your browser to ensure it’s working.

001     #pinboard ul li {
  002         position:        absolute;
  003         top:            200px;
  004         left:            460px;
  005         ... (as before)
  006     }

12. Add some rotation

We’ve now got a great little animation that scatters the Polaroids into place when the page loads, but it doesn’t look natural because everything is aligned perfectly. We need to introduce rotation to get a more organic look. We can do this using CSS, but to achieve a random degree of rotation, we’ll use JavaScript to calculate a rotation value then apply it using jQuery. Add the following code inside the .each() function.

001         $(“#pinboard ul li”).each(function(){
  002             xpos = Math.floor(Math.        random()*920);
  003             ypos = Math.floor(Math.        random()*420);
  004             rotation = Math.floor(Math.    random()*15);
  005             if(Math.floor(Math.random()*11)>5) {
  006                 rotation = rotation * -1;
  007             }
  008             $(this).data(“rotation”,rotation);
  009             $(this).delay(1000).        animate({top:ypos,left:xpos}).css({webkitTr    ansform:”rotate(“+rotation+”deg)”,MozTransform:    ”rotate(“+rotation+”deg)”,msTransform:”rotate(“    +rotation+”deg)”,transform:”rotate(“+rotation+”    deg)”});
  010         }).draggable();

13. Making sense of it

We’ve repeated our random number trick to set a random degree of rotation for each list item. Having every Polaroid rotate in the same direction would defeat the purpose of including it, so we use a second random number to decide whether to rotate a positive or negative amount. Finally, our new code applies CSS3 rules for the Transform selector, adding vendor prefixes as necessary for each browser.

14. Go one better

Set up a new JavaScript document and link it into your page via script tags. Make sure your script appears beneath the jQuery and jQuery UI script calls, so that both have loaded into your page. Next, add the code below to enable drag-and-drop interaction with each Polaroid. Save and test.

001 -webkit-transition:    0.2s         -webkit-transform linear;
  002 -moz-transition:    0.2s         -moz-transform linear;
  003 -ms-transition:    0.2s         -ms-transform linear;
  004 -o-transition:        0.2s         -o-transform linear;
  005         transition:    0.2s         transform linear;

15. Add a new state

The code we just added tells the browser to use native rendering to transition between different states for the Polaroid, over a period of 0.2 seconds. To see this in action, we need to add a new state to the Polaroid when it’s being dragged. Luckily jQuery UI
adds a class to the element when dragging is in progress, so we can add a rule that targets this:

001     .ui-draggable-dragging {
  002 -webkit-transform:            rotate(0deg) scale(1.2) !important;
  003 -moz-transform:             rotate(0deg) scale(1.2) !important;
  004 -ms-transform:             rotate(0deg) scale(1.2) !important;
  005 -o-transform:                 rotate(0deg) scale(1.2) !important;
  006         transform:        rotate(0deg)     scale(1.2) !important;}

16. CSS3 rules

Load the page in your browser to see how powerful CSS transitions can be. We’ve created a rule that scales the Polaroid up 120% its normal size, and sets it to have no rotation. When you start dragging, the Polaroid will grow and straighten. If you’re using a browser that supports transitions, you’ll also get a smooth animation between the states, all without scripting!

17. Tidying up

We’ve still got a little to do to ensure everything looks and works fine. First, you’ll have noticed that as you drag photos around, they can go beneath others on the page. We can solve this by adapting our JS to increment the z-index for the element you’re dragging. The full code is on the disc.

001 var zindex = 50;
  003 $(document).ready(function(){
  004     // Create your interaction code here
  005     $(“#pinboard ul li”).each(function(){
  006             xpos = Math.floor(Math.        random()*920);
  007             ypos = Math.floor(Math.        random()*420);
  008             rotation = Math.floor(Math.    random()*15);
  009             if(Math.floor(Math.random()*11)>5) {
  010                 rotation = rotation * -1;

18. New rotations

When the Polaroid is dropped following a drag, it would be nice for it to fall back into a new position, complete with a fresh rotation value. As you’ve seen, we can pass in some code to be executed when the dragging starts, so let’s do the same for when the dragging ends. Again, the complete code is on the CD.

001        .draggable({
  002            start: function(){
  003                zindex = zindex + 1;
  004                $(this).css({zIndex:zindex});    005
  006            },
  007            stop: function(){
  008                rotation = Math.floor(Math.    random()*15);
  009                if(Math.floor(Math.random()*11)>5) {
  010                    rotation = rotation * -1;    010                    }                       
 010                    $(this).data("rotation",     rotation);

19. Test again

By now you should have a completely functioning page with Polaroids that automatically animate into an initial position, can be dragged and dropped, grow when you start dragging and fall back when you stop. Check in each browser to ensure it works as expected, paying particular attention to areas where vendor prefixes have been used.

20. Final polish

We can add a final touch to the design by applying some styles to the instruction panel. In this case, we decided to go with a notepad-style panel, and you can find our artwork on this issue’s cover disc. Add the CSS code (which is available in its entirety on the CD) to render this into your page design.

001  #instructions {
  002         position:        absolute;
  003         top:            10px;
  004         left:            -50px;
  005         width:            292px;
  006         padding:        100px 50px;
  007         background:            transparent url(notepad.png) no-repeat top     left;
  008 -webkit-transform:    rotate(-    10deg)     !important;
  009 -moz-transform:     rotate(-    10deg)     !important;
  010 -ms-transform:     rotate(-10deg)     !important;

21. Tailor the text

The heading and paragraph text doesn’t quite render perfectly cross-browser due to differences in the default amount of margin, padding and font size. Add the step code to set your own rules and achieve consistency. Once you’re done, test in your browser to see the final design in all its glory.

001      #instructions h1 {
  002         margin-bottom:    0;
  003         padding-bottom:    0;
  004     }
  005     #instructions p {
  006         margin-top:    0;
  007         padding-top:    0;
  008         margin-bottom:    10px;
  009     }

22. Take it further…

The code we’ve developed here can be used with as many images as you like and should continue to work perfectly well. You could take the effect further by adding a custom texture/background to each Polaroid, changing the drop shadow when the Polaroid is being dragged, or allowing the images to be stored in boxes. Let us know what you come up with!


Create 3D transform effects with CSS and HTML

Take control of your backgrounds with CSS3