Live DemoDownload Source Code

Getting Started

First we should download a local copy of jQuery and store this along with the other project files. I am creating an index page along with an external stylesheet named styles.css.

Now inside the body I am setting up an unordered list of image items. Since these thumbnails are all different sizes, the display will look different based on image dimensions. I am using the HTML width and height attributes for setting up custom values. It gives the thumbnail images extra time to load so the GIF itself doesn’t lag too much.

This code sample only includes two items from the entire list. For each image I’ve saved a copy of the animated GIF, along with a solid JPG thumbnail. This thumbnail object is wrapped by an anchor link which points towards the animated GIF image. So now when the user clicks on a thumbnail it will lead directly to the animation.

But similarly we can use this href value as a variable in jQuery. So whenever the user hovers on top of a thumbnail image, we simply replace the image src to display the animated GIF. Note that the thumbnail and the GIF are both sized at the exact same dimensions. This way our HTML width/height settings should work perfectly on either image.

CSS Styles

There isn’t a whole lot of CSS to cover but I want to explain the setup for my core gallery. #w is the outer wrapper which is fixed at 750px width. Inside we have a #content div which is an inner container for the thumbnails. I’ve labeled the unordered list with an ID of #giflist for the sake of clarifying my jQuery selector.

I am only styling the inner list items so they can float left alongside each-other. Naturally once the next image is too big it will break down onto a new line. There is some extra spacing with margins to ensure plenty of room between thumbnails.

Also since all these internal elements are floated, the unordered list would typically have no height value. It would be taken out of the page flow completely without the use of a .clearfix class. Obviously we could add more stylish interface traits using CSS3 but these fundamental properties are enough to get the gallery working smoothly.

Image Replacement with jQuery

Adding the final piece to this puzzle comes with a small jQuery event handler. At the bottom of my page before the closing tag we need to open a new JavaScript block. The anchor links surrounding the images are not block-level and so they aren’t something we can target with an event listener. Instead I am targeting the images themselves, and we run a new function every time the user hovers over one of these image thumbnails.

The jQuery .hover() method takes in two callback parameters which I’ve written as functions. The first will trigger when the user’s mouse enters the selector, and the 2nd function triggers once the user’s mouse leaves the selector. When they first hover on top of the image we need to pull out the corresponding href value from the outer anchor link.

Then we can replace the image src value to now display our animated GIF image. It will be sized down according to the HTML width/height attributes but it will also be fully loaded into cache memory. You may have noticed I am using an HTML5 data attribute with the name data-orig. Once we replace the image src value with the animated gif there is no easy way to get back to the thumbnail picture.

So instead of saving this into a variable we just keep it local inside the img tag. Now when the user moves their mouse away from the image, we simply replace the source with a copy of the data-orig value. This puts the non-animated thumbnail back in place while the animated GIF is merely a click(or hover) away.

Live DemoDownload Source Code


The use of a JavaScript library such as jQuery provides excellent support for newer web browsers. One thing to note is on mobile devices, users will have to tap each thumbnail to view the animation in a new window. But the UI has been designed to work perfectly for all modern browsers and even older legacy versions with JavaScript enabled. Feel free to download a copy of my source codes and see if you can implement this effect on any similar web projects.

For more related resources: