Add zoom icon to images using CSS (and jQuery, of course)

April 6, 2009

I like to read articles on webdesignerwall.com. Not just because of its content, but also because of its great design. I like one simple effect this blog has and that is a zoom icon that is being shown when you hover an image. In this simple tutorial, I'll show you how to do it in two ways: CSS way and jQuery way.

Before we start, take a look at the live demo, or see it live on webdesignerwall.com.

View live demo

CSS way

This can be easily done with pure CSS. Take a look at the code below. Inside the each link there are an empty <span> element and image.


<div id="gallery1">
    <h2>CSS solution</h2>
    <a href="3029990904_d10cc4fd9d_o.jpg">
        <span></span>
        <img src="3029990904_6fc619349d_m.jpg" alt="" />
    </a>
    <a href="3036302292_d37001ed77_o.jpg">
        <span></span>
        <img src="3036302292_61f44a917c_m.jpg" alt="" />
    </a>
</div>

So, the key is to have absolutely positioned <span> inside the relatively positioned link. Span's have a background image that is our zoom icon, actually. Span's width and height have to be the same as icon's size. You can set the location of zoom icon by setting its top/bottom/left/right position.


#gallery1 {width:100%; overflow:hidden;}

#gallery1 a {position:relative; float:left; margin:5px;}

#gallery1 a span { display:none; background-image:url(zoom.png); background-repeat:no-repeat; width:48px; height:48px; position:absolute; left:15px; top:15px;}

#gallery1 img { border: solid 1px #999; padding:5px;}

Spans will be hidden initially, but if we add just one more line of code, they will be shown on each hover.


#gallery1 a:hover span { display:block;}
 

jQuery way

Things cam be even simpler if we use jQuery. We can, for example, get rid of <span> elements in the structure and add them dynamically. Or we can add an animation effects. So in this case, html code will be somewhat simpler:

<div id="gallery2">
    <h2>jQuery solution</h2>
    <a href="3029990904_d10cc4fd9d_o.jpg">
        <img src="3029990904_6fc619349d_m.jpg" alt="" />
    </a>
    <a href="3036302292_d37001ed77_o.jpg">
        <img src="3036302292_61f44a917c_m.jpg" alt="" />
    </a>
</div> 

There are no <span> elements inside links. We can add hem dynamically instead:


$("#gallery2 a").append("<span></span>");

Pretty much easy. Now let's add some functionality. Instead of handling hover with CSS we'll do it through jQuery and add fade-in and fade-out effects along the way.


$("#gallery2 a").hover(function(){

    $(this).children("span").fadeIn(600);

},function(){

    $(this).children("span").fadeOut(200);

});

Zoom icon will slowly fade in on hover a link, and quickly fade out when leave it. So the complete jQuery code will look like this:


$(document).ready(function(){

    $("#gallery2 a").append("<span></span>");

    $("#gallery2 a").hover(function(){

        $(this).children("span").fadeIn(600);

    },function(){

        $(this).children("span").fadeOut(200);

    });

});

Do you use some other way to do this or have something similar?

Let's discuss this on twitter.

27 Comments

  • Gaya (April 6, 2009)

    Hey Janko, looks cool =) Really easy to use, good job.
    The thing I see in many of the jQuery tutorials out there is that the animations are put in some sort of queue. So when I hover over the images back and forth, the animations are remembered and the image is fading in / out. Is it a jQuery thing, or could it be helped? (I want to check out jQuery myself now that I’ve used scriptaculous for so long.)

  • Janko (April 6, 2009)

    Gaya: To be honest, I’ve never thought about it – but that is a good subject to research & experiment! :D

  • Gaya (April 6, 2009)

    I’ve seen it on some websites that sell products. In scriptaculous there is a .cancel() function so you can cancel the animation that is in progress. Helped me with the Garage door effect on Gaya Design. Would be weird if jQuery didn’t have anything like that. I’m going to look it up in the docs. haha

  • David Walsh (April 6, 2009)

    Nice work Janko, but I think it might be more function if you kept the icon there at all times. The only way a user knows they can see a larger version is if they hover over it, whereas if you leave the icon there at all times the user can spot that right away.

    Cool effect though!

  • Karl Swedberg (April 7, 2009)

    Hey guys,
    The animation queue buildup is a pretty common problem. See <a href="http://www.learningjquery.com/2009/01/quick-tip-prevent-animation-queue-buildup">this tutorial</a> for a way to avoid it.

  • Janko (April 7, 2009)

    David, If you have just a few images on a page, yes. In case of galleries, for example, there might be too much zoom icons :)

    Karl, thanks for sharing, you saved my time :D

    Gaya, it’s .stop() method, thanks to Karl!

  • Davide Espertini (April 7, 2009)

    Excellent tutorial Janko! :D

  • Gaya (April 7, 2009)

    Ah! Thanks Karl! This should help me a lot when I want to try jQuery. Thank you.

  • Neil (April 7, 2009)

    Very cool, incorporate that with a lightbox of some sort and you are done

  • L.M (April 8, 2009)

    Good Job!!

  • Pradeep (April 8, 2009)

    Nice one, I am thinking of removing the joomla plugin that I am currently using in my website and use this one. Do you think integrating this plugin to a joomla site would be a tough job? Anyways, you have done a great job!

  • Soh Tanaka (April 8, 2009)

    I would of done it the same way, nice and simple :-) Great tutorial!!

  • em (April 9, 2009)

    What with animation on IE? There is problem with transparency while fading.

  • Janko (April 9, 2009)

    Davide, LM: thanks!!

    Neil: of course, adding lightbox (or similar) into this story is a good idea.

    Pradeep: I’ve never worked with joomla, I really don’t know about it.

    Soh Tanaka: Glad you like it!

    em: yes, I noticed the issue – damn IE :)

  • Webdesign Meppel (April 9, 2009)

    Very well done! I prefer the jQuery version. It just has that extra touch and I think that’s one of the reasons jQuery should be used!

  • Scott Radcliff (April 10, 2009)

    Love the concept. Although I haven’t coded it, I think a nice touch would be to detect the position of the cursor and placethe span accordingly. If some people just graze across the image, they may miss the magnifying glass.

  • Janko (April 11, 2009)

    Webdesign Meppel: Agree!

    Scott: Could be nice effect, have to try it. Maybe placing icon in the center of the image would also be easy to notice?

  • Pradeep CD (April 14, 2009)

    Great tut…

    I enjoyed it….

    Thanks

  • bobster (April 28, 2009)

    Merci pour votre excellent travail.

  • Module23 (May 25, 2009)

    Your CSS-way is a great technique. Thanks man!

  • Shibi Kannan (August 2, 2009)

    Very nice tutorial and really cool zoom effect. I have one small issue – how do you get the page to reload the gallery after the original click to zoom we need a way to click back to gallery view. It will be nice if you could suggest a JQuery method instead of having to reload from browser.

  • Shibi Kannan (August 2, 2009)

    Also I noticed this nice country flag thing you have here in the comment box. I found some were missing icons like Sri Lanka for example. But it is really cool effect.

  • Janko (August 2, 2009)

    Thanks everyone!

    Shibi: You can implement lightbox plugin or similar, I wanted to keep demo simple. Sorry for the missing flags, will fix that soon :)

  • Bla┼ż (August 18, 2009)

    IE6 as we all know can’t display transparent images, but IE7 has problems with transparent image fading.. transparency fixes should fix this. Oh and also the non animated demo doesn’t work in IE6 (in IE tester).

  • Juarez P. A. Filho (August 28, 2009)

    So… Simple and cool. Nice tip and .stop() is a lifesaver. =D

  • James Dalton (September 5, 2009)

    This is great, Im gonna try it on a new site that I am developing. Thanks for taking the time for writing this zoom tip.

  • Pavel Soukenik (September 6, 2009)

    Often, you can achieve the zoom image without manually adding spans in the content. Check http://soukie.net/2009/08/20/typography-and-css/#example