The other day I was handed a design for a large navigation menu with images. An image would show when a user hovered over the individual menu item - pretty common navigation UI element.

My biggest concern was how to responsively load these images only when the visitor required them, especially because they are not visible to the user unless she engages with the navigation, which may not happen all the time. So while doing nothing would still work, I wanted to find a way to only fetch the image only in the event the user needed it.

Let's see the code.

My approach to solving the problem

The problem - the navigation contains a large amount of images, which may impact site load time.

The solution - only load a navigation image when user hovers over the associated menu item.

The technique - on hover, replace a span tag with an img tag and copy the attributes over.

The markup

I've created a span element with a custom attribute named data-original, which contains the path to my image.

<div class="container">
  <h1 class="trigger">Hover over me to fetch an image</h1>
  <span data-original="">

The JavaScript

I have an event listener for the .trigger class that will do a quick search and replace, copying what I have in the data-original to the src.

$(document).ready(function($) {

  $('.trigger').hover(function() {

   // find our span
   var elem = $(this).find('span');
   // get our img url
   var src = elem.attr('data-original');

   // change span to img and use the value from data-original to populate the src attribute
   elem.replaceWith('<img src="' + src + '"/>');


CodePen demo

I have a red box that is the span tag. Once you hover over the box, the JS fires and loads the image.

See the Pen Lazy Load on hover using span swap by Jacob Arriola (@jacobarriola) on CodePen.

Progressive Enhancement

Well, the image contains other meta data that I didn't include here such as the post title and excerpt. Therefore, in the event that JavaScript is not available, the user will still be able to tell what she is looking at and can still click through - yay!

What About SEO?

From what I understand, we shouldn't get penalized since the DOM intially reads as a span tag. I was orginally going to use an img tag and just swap out attributes, but was concerned about search engines penalizing me for having an img tag without a src attribute.