How to Code a Hover-to-Animate GIF Image Gallery

Animated GIF images are popular on the Internet because they can be easily shared and consumed rather quickly. Using basic HTML you can embed images into a page which feature animation, without relying on any other technologies. Granted – there are plugins for animating sprites or backgrounds – but GIFs are a totally different concept.

In this tutorial I want to demonstrate how we can build an image gallery which optimizes the display of animated images. You can see a very similar feature on Giphy which is also where I downloaded the images for my demo. I am coding my own method which doesn’t exactly follow the same process as Giphy – but the end result is practically identical and works great for all modern browsers.

The Ultimate Designer Toolkit: 2 Million+ Assets

Envato Elements gives you unlimited access to 2 million+ pro design resources, themes, templates, photos, graphics and more. Everything you'll ever need in your design resource toolkit.

Explore Envato Elements

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.

<!doctype html>
<html lang="en-US">
<head>
  <meta charset="utf-8">
  <meta http-equiv="Content-Type" content="text/html">
  <title>Hover-to-Animate GIF Gallery - Design Shack Demo</title>
  <meta name="author" content="Jake Rocheleau">
  <link rel="shortcut icon" href="https://designshack.net/favicon.ico">
  <link rel="icon" href="https://designshack.net/favicon.ico">
  <link rel="stylesheet" type="text/css" media="all" href="css/styles.css">
  <script type="text/javascript" src="js/jquery-1.10.2.min.js"></script>
</head>

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.

<body>
  <div id="topbar">
  <a href="https://designshack.net">Back to Design Shack</a>
  </div>
  
  <div id="w">
    <div id="content">
      <h1>Hover-to-Animate GIF Gallery</h1>
        <p>Hover over an image to view how the gif animation looks. Alternatively click the thumbnail to open a full version of the gif in a new tab. All images are courtesy of <a href="http://giphy.com/">Giphy</a>.</p>
        
        <ul id="giflist" class="clearfix">
          <!-- http://giphy.com/gifs/3u1bKI2ve3G3S/ -->
          <li><a href="images/eating-anim.gif" target="_blank"><img src="images/eating-anim.jpg" data-orig="images/eating-anim.jpg" width="300" height="225"></a></li>
          
          <!-- http://giphy.com/gifs/e2QYPpUe8WmpG/ -->
          <li><a href="images/seinfeld-anim.gif" target="_blank"><img src="images/seinfeld-anim.jpg" data-orig="images/seinfeld-anim.jpg" width="250" height="250"></a></li>

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.

/** page structure **/
#w {
  display: block;
  width: 750px;
  margin: 0 auto;
  padding-top: 30px;
  padding-bottom: 45px;
}

#content {
  display: block;
  width: 100%;
  background: #fff;
  padding: 25px 20px;
  padding-bottom: 35px;
  -webkit-box-shadow: rgba(0, 0, 0, 0.1) 0px 1px 2px 0px;
  -moz-box-shadow: rgba(0, 0, 0, 0.1) 0px 1px 2px 0px;
  box-shadow: rgba(0, 0, 0, 0.1) 0px 1px 2px 0px;
}

/** gif image list **/
#giflist {

}

#giflist li {
  display: block;
  float: left;
  margin-right: 35px;
  margin-bottom: 40px;
}

/** clearfix **/
.clearfix:after { content: "."; display: block; clear: both; visibility: hidden; line-height: 0; height: 0; }
.clearfix { display: inline-block; }
 
html[xmlns] .clearfix { display: block; }
* html .clearfix { height: 1%; }

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.

$(function(){
  $('#giflist li a img').hover(function(){
    // on mouse enter
    var customdata = $(this).parent().attr('href');
    $(this).attr('src',customdata); 
  }, function(){
    // on mouse leave
    $(this).attr('src',$(this).attr('data-orig'));
  });
});

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

Closing

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.