Web Development

How to create an image hover-preview effect using jQuery

Ryan Boudreaux includes all the code snippets you'll need in this demo of how to create an image hover-preview effect using HTML, CSS, and JavaScript.

In this tutorial, I will show you how to leverage the power of jQuery to create a hover-mouseover image preview with an image gallery on one HTML document page. For this demonstration, you will need a basic knowledge of CSS, JavaScript, and HTML coding techniques. We will also incorporate several HTML5 and CSS3 elements into the final piece. The files utilized in this demonstration are available here. My muse for this tutorial is credited to Alen Grakalić, and his efforts with Css Globe.

First, we will create a style sheet and name the file styles.css, then save it to a sub-directory named css under the web directory. These will define the body, the main class, the gallery class, h1, h2, anchor, pre, image, unordered list, and list items, and the preview id. I will describe in more detail several specific styling definitions as they apply to several of these elements below. The CSS code also includes several CSS3 stylings for box shadow and text shadow; the code contained within the style sheet is shown below:

@charset "utf-8";
/* CSS Document */
body {
      margin:0;
      padding:40px;
      background:#B1B1B1;
      font-family:Tahoma, Geneva, sans-serif;
      font-weight:normal;
      color:#555;
      line-height:180%;
}
.main {
      background-color:#DDFBEF;
      width:460px;
      margin-left:100px;
      margin:0 auto;
      padding:10px;
      min-height:500px;
}
.gallery {
      background-color:#EBEBEB;
      min-height:150px;
      padding: 5px 0px 10px 10px;
      box-shadow: 2px 2px 3px rgba(150, 150, 150, .75);
      margin-bottom:25px;
      width:445px;
}
h1 {
      font-size:28px;
      font-weight:normal;
      color:#22411D;
      text-shadow: 1px 2px 1px rgba(150, 150, 150, .75);
}
h2 {
       font-size:22px;
       font-weight:normal;
       color:#526F78;
       text-shadow: 1px 2px 1px rgba(150, 150, 150, .75);
}
a {
       text-decoration:none;
      color:#f30;
}
pre{
      display:block;
      font-family:Tahoma, Geneva, sans-serif;
      font-weight:normal;
      padding:7px;
      border:3px solid #bae2f0;
      background:#e3f4f9;
      margin:.5em 0;
      overflow:auto;
      width:800px;
}
img{
      border:0px;
      box-shadow: 2px 2px 3px #555562;
}
ul,li{
      margin:0;
      padding:0;
}
li{
      list-style:none;
      float:left;
      display:inline;
      margin-right:10px;
}
#preview{
      position:absolute;
      border:3px solid #ccc;
      background:#333;
      padding:5px;
      display:none;
      color:#fff;
      box-shadow: 4px 4px 3px rgba(103, 115, 130, 1);
}
Next, we will set up the images that will be used for the demonstration, and these will be contained in a web sub-directory named images. Each image requires the original, which in this demonstration, are set to a width of 400 pixels and a height of 320 pixels, and the resized thumbnails are set to 100 x 80, saved as JPGs (ex., 1t.jpg). The images used in this demonstration are stock clip-art (royalty free), displayed in Figure A:

Next, we will start our HTML document with HTML5 elements, setting the doctype, language, head, meta, title, description, scripts and external linking to the style sheet. The file is saved in the root of the web directory as index.html, and the code snippet is displayed below:

<!DOCTYPE html>
<html lang="en">
  <head>
   <meta charset="utf-8">
    <title>Image Preview using jQuery</title>
    <meta name="description" content="Image Preview using jQuery">
    <script src="js/jquery.js" type="text/javascript"></script>
    <link rel="stylesheet" type="text/css" href="css/styles.css" media="screen" >
</head>
<body>

Notice the script source is pointing to the "js" sub-directory, which is contained within the web directory. This is the jQuery source file, which is required for the jQuery scripts to run within the document.

Next, we will create a <section> and two <articles> which will contain two simple galleries, one for the "Landscape" gallery and the other for "Still Life" gallery. The HTML code is displayed below:

<section class="main">

  <h1>Image Preview using jQuery</h1>
   <article class="gallery">
    <h2>Landscape Gallery</h2>
      <ul>
        <li><a href="images/1.jpg" class="preview" title="Banff Alberta Canada"><img src="images/1t.jpg" alt="gallery thumbnail" /></a></li>
        <li><a href="images/2.jpg" class="preview" title="Plains - Africa"><img src="images/2t.jpg" alt="gallery thumbnail" /></a></li>
        <li><a href="images/3.jpg" class="preview" title="Farmland"><img src="images/3t.jpg" alt="gallery thumbnail" /></a></li>
         <li><a href="images/4.jpg" class="preview" title="Prairie"><img src="images/4t.jpg" alt="gallery thumbnail" /></a></li>
      </ul>
    </article>
    <article class="gallery">
      <h2>Still Life Gallery</h2>
       <ul>
         <li><a href="images/5.jpg" class="preview" title="Fruit Flowers Bread"><img src="images/5t.jpg" alt="gallery thumbnail" /></a></li>
         <li><a href="images/6.jpg" class="preview" title="Baking"><img src="images/6t.jpg" alt="gallery thumbnail" /></a></li>
         <li><a href="images/7.jpg" class="preview" title="Fruit on Table"><img src="images/7t.jpg" alt="gallery thumbnail" /></a></li>
         <li><a href="images/8.jpg" class="preview" title="Vegetables"><img src="images/8t.jpg" alt="gallery thumbnail" /></a></li>
       </ul>
     </article>
</section>

Notice the image anchors are given a class="preview", which sets the absolute position, border, background color, 5 pixel padding, and a box shadow for each image. The class is also called in the jQuery functions, which will be displayed and explained below. The class="gallery" sets the background color to #EBEBEB, the minimum height to 150 pixels, a padding of 5 pixels 0 pixels 10 pixels 10 pixels, with a top margin of 25 pixels, and a width of 445 pixels.

Next, we will set the scripting with the opening <script> tag to JavaScript and start the jQuery with the document ready function. As a general rule, I like to place all my in-line scripting at the bottom of the HTML file just before the closing </body> tag, the starting script code is displayed in the code snippet below:

<script type="text/javascript" language="javascript">
// Kick off the jQuery with the document ready function on page load
$(document).ready(function(){
      imagePreview();
});

Next, we will set the x and y offset configurations which will set the horizontal and vertical adjustments that apply to how far down and how far to the right of the thumbnail the image preview will be displayed. The code snippet is displayed below:

// Configuration of the x and y offsets
this.imagePreview = function(){
            xOffset = -20;
            yOffset = 40;

The xOffset = -20 brings the preview down 20 pixels relative to the thumbnail, and the yOffset = 40 brings the preview to the right 40 pixels relative to the thumbnail.

The next code snippet sets the hover function along with the caption title; it also sets the offsets and the fade in to slow.

    $("a.preview").hover(function(e){
        this.t = this.title;
        this.title = "";
           var c = (this.t != "") ? "<br/>" + this.t : "";
         $("body").append("<p id='preview'><img src='"+ this.href +"' alt='Image preview' />"+ c +"</p>");
         $("#preview")
            .css("top",(e.pageY - xOffset) + "px")
            .css("left",(e.pageX + yOffset) + "px")
            .fadeIn("slow");
    },

The next functions remove the preview and the caption title when the hover is outside of the image area, along with the "mousemove" which allows the preview to move along in relation to where the cursor is within the thumbnail, and finally, the closing script tag:

    function(){
        this.title = this.t;
        $("#preview").remove();
    });
    $("a.preview").mousemove(function(e){
        $("#preview")
            .css("top",(e.pageY - xOffset) + "px")
            .css("left",(e.pageX + yOffset) + "px");
    });
};
</script>
The final image gallery as displayed in Chrome 18.0.1 is shown in Figure B:

And next, an example of the hover preview effect over the second landscape image, as shown in Figure C:

Again, you can download all the files for this demo of the image-preview effect here.

For further reading, check out these resources:

About

Ryan has performed in a broad range of technology support roles for electric-generation utilities, including nuclear power plants, and for the telecommunications industry. He has worked in web development for the restaurant industry and the Federal g...

2 comments
Mark Simchock
Mark Simchock

I'm no jQuery expert but perhaps it would have been a bit more efficient to set up everything, or most of it, in the markup and then just use jQuery to .show() and .hide() or even animate(). Once you append() and remove() and then append() again, it's "wasteful", yes? Also, is there a reason you elected to use a link instead using a data element within the img? Hover or even .click for that matter will work on images just as easily as links, correct? Don't get me wrong, I understand there's more than one way to skin the jQuery cat. That said, as someone who is trying to learn the library, I often lose sleep wondering, "Yes, it works. But did I do it as thoroughly as possible?" Working examples are easy to find but optimized ones not so much so. Perhaps this is something you can visit in future tuts? Thanks.

kburrows
kburrows

I can't tell from the code (which would be nice if it used CSS) if the pop out works similarly to LightBox, which uses jquery and CSS (really simplifies the code). Anyone had any success with this code? Are there any working samples to demonstrate its features? My bad...found the sample link. It is not like Lightbox as this is on a rollover preview and not an overlay on the page.