CSS Photo Zoom

After reading Pixy’s clever Fast rollovers, no preload needed method for using a single background image for multiple hover states, it got me thinking. What if the concept was used to offer a zoomed view of a thumbnail image, right inline on the page, again using a single image?
Here’s the example, where I’ve created a single JPG image that contains both the thumbnail and zoomed photo below it. I then use Pixy’s idea of changing the background-position as well as the width and height for the :hover state to hide the thumbnail, but reveal the larger zoomed photo.
I’m not entirely sure that this is even a practical application of the concept — but it seems like it could work pretty well in certain circumstances, so I thought I’d throw the idea out there.
What to do with un-styled viewers? I thought that making a “View image” link that points directly to the thumbnail/zoomed photo would be acceptable, then hiding the link text with recently discovered text-indent: -1000em; trick. I’m sure there are other, more elegant things to do with a non-styled view, but this seemed the easiest, without creating an additional separate image.
I’ve only tested this on Mac: Camino, IE5.2 and Safari.


  1. Chris says:

    Not bad, I like it. Although when you do actually think about the process of this, it is simple. Surprised it has been worked on before actually.
    Tested on Win with IE6 and Mozilla. Works.

  2. Hugh says:

    Neat trick… but in Safari once the image is zoomed it doesn’t disappear… the image continues to cover the text… of course that may be on purpose… I noticed that the text reflows in IE5.2, doesn’t in Safari (for me)…

  3. Dan R. says:

    Dan, this is a great variation on pixy’s technique! I’ll have to play with it and see if I can come up with other uses.
    Works on IE5.1/OS 9 too

  4. Sunny says:

    Works in Win/IE 6 and Win Mozilla/Firebird.
    Really nice.

  5. stombi says:

    Tested on GNU/Linux with Konqueror 3.1.1 and Mozilla-firebird 0.6.1-2. Works.

  6. Dan says:

    Thanks much for all the other browser tests.
    Hugh – that’s exactly right – the text should always be hidden in CSS-enabled browsers. Strange about the text not re-flowing in Safari. I’m seeing it behave properly over here.
    Dan R. – Excellent, I quickly put the demo together in hopes that we’d see other cool uses.

  7. Bob says:

    Moz1.4/Win2K likes it, too.

  8. The text is not reflowing either for me in Safari and the image doesn’t disapear. (OS X 10.2.6 with Safari v85)

  9. Ruth says:

    Tested on Win (2K Pro) with the following browsers:
    IE 6.0 – works
    Netscape 7.01 – works
    Firebird 0.6.0 – works
    Firebird 0.6.1 – works
    Netscape 3.0 – degrades gracefully
    Netscape 4.7 – fails

    Probably would degrade gracefully in Netscape 4.7 if you linked to an external stylesheet via @import rather than making the styles inline.

    Nice work!

  10. Dave says:

    I had the same problem as others with Safari (v85). Very cool idea otherwise

  11. Tom says:

    Cool, works fine on IE6 on WinXP, the text reflows nicely. One thing that bothers me which I’ve seen before is that when you float an image right at the start of block of text, the first line of the text gets indented a bit. I’ve noticed this in IE 5 and 6, it’s not a big deal but it always bugs me.

  12. stylo~ says:

    Kind of messy to prepare though, huh? Better off just dynamically resizing or cropping the original large image.

  13. Tested on win2k/IE5.0 – works.

  14. amd says:

    Wonderful ;)
    Works 100% with Epiphany 0.8.4 and Opera 7.20 B4 on Gentoo/GNU/Linux.
    I’m wondering though, how good it looks when text is set to justified.

  15. amd says:

    Hm.. i lied. On Epiphany, some weird line appears on pictures. It seems like the image is interpreted as textual link and is given a proper underline. This can be fixed with adding text-tecoration: none; to #zoom a { … }.
    PS. Have you checked, what happens when picture is not found? Blank picture ;(
    No idea about this one.

  16. JumpTheGap says:

    Cool staff Dan, thank you!
    Surely I’ll use it somewhere.

  17. Ryan Carter says:

    Now that’s using your head!

  18. Adam says:

    I personally think this is a better alternative to offering close ups of thumbs than say, Wired’s approach of opening a whole new window. And, when you think about it, you don’t necessarily have to surround it with text. You could just have a group of photos, or a photo with a caption below it, etc…

  19. Mike says:

    Works fine in my PC versions of: IE 6.0, IE 6.1, Opera 7, Moz 1.4, Netscape 7.1. It is also accessible by: MSN TV Viewer 2.8 and Amaya(!). Good job. Well Dan. ;-)

  20. Alex says:

    Very nice.
    If you’re looking for a more gracefully degradable solution, though, why not keep your HTML in the form of a standard thumbnail? That is, an img of the thumbnail within an a linking to the full-size image.
    Then, using CSS, you can set the background-image of the a element to the full-size image. And for :hover, push the img out of the way (perhaps with the negative text-indent trick) and resize the a to fit the full-size image.
    Actually, I haven’t tried any of the above, so maybe I’m missing something. Still, it doesn’t rely on any tricky background positioning, and you don’t have to modify your existing HTML.

  21. Alex says:

    Finally found the time to do some testing.
    Here’s my take on the “CSS Photo Zoom” using the method I described above.
    Tested in Windows:
    Internet Explorer 6 – Pass.Firebird 0.6 – Pass.Netscape 7 – Pass.Opera 6 – Photo zoom doesn’t work. Opera 6 displays an ordinary thumbnail. Still can’t figure it out.Netscape 4 (inline) – Fails completely.Netscape 4 (@import) – Displays an ordinary thumbnail.
    If someone would test this on some Mac browsers, that would be great.

  22. Eric says:

    Hey very nice! Great tip. Thanks

  23. Mark Wubben says:

    Good idea, Alex. However, it isn’t very useful in thumbnail pages. You’d need to specify a class for each thumbnail, and in that class specify the background image (in your example “zoom.jpg”). Otherwise it would only be useful for one image.
    So instead we could use the CSS-3 attr() function. This would limit the support down to Gecko-based problems, but you can work around that using JavaScript.
    I got up my little testcase and found that this wasn’t working.. Any ideas on this?

  24. Dan says:

    Alex – I like it. Certainly degrades nicely.
    A general note about any of the CSS examples I post here — I tack the CSS code to the head of the document purely for the ease of dissection. In the real world, one would probably want to use @import to protect older browsers.

  25. eric says:

    Alex’s version displays properly in Opera 7.1 – but with the side effect of adding a gigantic horizontal scrollbar at the bottom.

  26. Pierce says:

    Hmm… this is pretty cool. But I don’t really like things messing with my text layout.
    As in, it’s very disconcerting to be reading text while moving your mouse across the screen (you don’t notice yourself doing this, but you do do both at once) and suddenly the text all shifts downwards, and you have to find your place again.
    But I’m sure a lot of other uses could be found for this. Ones that don’t involve layout change.

  27. manu says:

    SuSE Linux, Mozilla 1.4/1.5a, firebird (Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.5a) Gecko/20030706 Mozilla Firebird/0.6) & galeon: works

  28. Paul G says:

    The concept is pretty cool, but how is this better than using large images as thumbnails by resizing them in the browser? I always thought it was exremely bad form to take (for example) an 800×600 picture and make it look like a thumbnail by deliberately setting the witdth and height with html. Seems to me that this technique is even worse, since you are making an even bigger picture to hold the thumbnail. If you are going to use the big picture as a thumbnail, it seems like you should just use css to resize the image instead of moving a bigger image around.
    I whipped up a quick demo, css is in the head (valid xhtml & CSS): http://www.paulpgriffin.com/css/zoom/css_zoom.html
    Tested in Moz 1.3, IE 6, and Opera 7.1
    P.S. (Please don’t look at the rest of my site, it’s been quite a while since I’ve done anything with it, I find it kind of embarassing these days :)

  29. Jeff Croft says:

    I agree. That was the first thing I thought when I saw this. Why not just use the full size image and resize it with CSS?
    That said, your example doesn’t seem to work in Safari. Great concept, though!

  30. Jeff Croft says:

    I’ve tweaked your version a bit, and it’s now working in Safari. I beliete it should work in most other browsers, too, but I haven’t tested it, yet.
    Basically, I added this rule:
    #zoom img:hover {

  31. Jeff Croft says:

    I tested my link above…
    IE6/Win: Works.
    Safari: Works.
    Netscape 7.2/mac: Works.
    IE 5.2/mac: Works.
    IE 5.5/Win: Doesn’t work (looks fine, just no zoom)

  32. Paul G says:

    Ah, I love a simple solution. Works fine in Moz 1.3, IE 6, and Opera 7.1.
    I still find it odd that it won’t work correctly in IE unless you add a rule for a:hover…

  33. Dan says:

    Paul and Jeff – I wasn’t exactly looking to present the optimal way of handling thumbnail photos — just a variation on Pixy’s “all-in-one-image” concept. Something to generate some ideas (which appears to be working :)
    It is of course, bad practice to resize an image using height and width attributes — unless the zoomed view is happening without a page refresh. Similar to pre-loading images when using javascript mouseovers, when the actual size is needed on the page.
    I like your resizing with CSS idea — although in some cases, resizing an image down with CSS (or within an img tag) can lead to a crappy looking thumbnail. Still, I like it.

  34. Jeff Croft says:

    IE/Windows doesn’t support the :hover pusedo-class on any element other than an anchor. It’s lame, and I have no idea why they did it that way, but that’s the way it is. That’s why you need a tag wrapper.
    Gotcha. You got me thinking about this, and for that, I’m thankful! I know the text-zoom isn’tnecessarily perfect, but it’s a great proof-of-concept.

  35. Paul G says:

    I know that IE won’t apply :hover to arbitrary classes, but that shouldn’t keep it from properly interpreting selectors constructed like this:
    #zoom a:hover img {
    /* styles */
    I found that this selector doesn’t work in IE until you add a generic selector as well:
    a:hover {
    Adding a rule for a:hover suddenly causes the other selector to work. It doesn’t matter what you put in the a:hover selector, there just has to be something there, or IE won’t honor any selectors with a:hover in their inheiritance chain.
    Doesn’t make a whole lotta sense to me…
    At any rate, it’s good to get the creative juices flowing again. (Thanks Dan & Jeff)

  36. Very cool effect.
    I’d recommend, however, to have the enlarge tool icon at the left top or left bottom of the photo. Given that the rollover happens the second you put your cursor anywhere in the image, I think having the icon closer to the initial point of the cursor’s entry into the image would make a wee bit more sense. It’s a tad jarring otherwise.
    But again, very cool.

  37. Jerotito says:

    Win 98 / ie 5.00 : works well.

  38. Jan Heck says:

    i tested it on win 2k mozilla 1.4 and IE 6. Wunderfull!!

  39. Wardak says:

    In response to amd’s request(13th from top) to see how this would look with JUSTIFIED text. Works great. The text is justified when the zoomed version of the image is displayed.

  40. PJB says:

    I think this would be a great solution for a problem I was having.
    I have some pictures that I want to mark up (with text, circles, arrows, etc.). I want to give people the option of easily seeing both marked and unmarked. All other image replacement techniques I have thought about cause quite a delay during the second image loading (since these will be larger-than-thumbnail size images). I am really going to have to take a look at this technique. Thanks for the idea.

  41. Lingo says:

    Hmmmm…this is basically another approach to the same thing that can be (and has been) done with the CSS CLIP property.
    Since I don’t have a lot of time to run experiments, does anyone know how this approach compares to the same technique with CLIP, especially with regards to cross-browser and backwards compatibility?
    Just curious.

  42. Leo says:

    Wonderfull new toy. I have a few comments, however.
    1, The large photo should be ABOVE the small one in the image to make sure the large image is available when you see the small one and hover mouse over it. An image on a webpage loads from the top to bottom.
    2, “It is of course, bad practice to resize an image using height and width attributes — unless the zoomed view is happening without a page refresh.” (Dan)
    Moreover, large image resized by browser using width and height doesn’t look nice. Photoshop’s job is much better.
    3, I have been always told that IMG should be used for images that brings information rather than being a mere decoration… :-)
    4, One serious problem with background-image concept is that IE doesn’t print then (by default) and IE and most browsers don’t save them along with the webpage (Save as webpage complete). While this is a minor problem with menu links, in case of these images it is not acceptable to most users who print or save pages.

  43. KuraFire says:

    First off…
    Dan C – nice idea, though the Reflow-effect is a shame.
    There was an article somewhere about why you should avoid Reflow, I just do it because I find it absolutely unacceptable that a page reflows due to me moving my mouse over a certain element. If I wanted to see stuff move on my screen just because I move my mouse, I’d go to some Flash site or play a game :)
    Anyhoo, that’s all not really relevant here. I tried to disable the reflow effect but I’ve only managed to got it to work in the Mozilla / Gecko engine so far. IE 5.0 (don’t know yet about IE 5.5 / 6) doesn’t particularly like to behave, seeing as how it doesn’t seem to have Any decent support for position: fixed on anything that is not a BODY tag. Ahwell, something to look into…
    What I did to cause reflow to stop (in Mozilla) was very simple. I put <span> tags around your <a href...> and added a few lines of CSS that would cause the property to ‘stick’. You can see the results on a silly directory on my ‘old’ site. It should work primarily the same as the original, in IE5.x, but in Gecko (and possibly Opera and what else not that supports some decent CSS) it will no longer cause document reflow.
    PS Dan, you should stop using the copyright unicode output in your pages’ source code, and start using &copy; instead – more compliant ;)

  44. Mike says:

    Cool stuff as usual Dan. One problem: I thought a thumbnail was there to avoid excessive download times? This causes the large image to be downloaded regardless of the users choice, no?
    [I know my comments is a bit late - Hope the move went well, just in the middle of a bunch of boxes myself...]

  45. Alex says:

    I get some rather annoying flashing when my mouse transitions from being over the image to not being. Like the entire picture is drawn for a moment. It’s also weird shifted down and too the left I think. It’s pretty annoying. I’m using Mozilla 1.6a btw.

  46. I found another use for this, one that I think would be more stylish: I’m designing an online user gallery for personal use and I thought it would look good if the thumbnails got a little bigger when doing a mouseover. Either that, or zoom in to the important part of said photo while keeping the thumbnail size intact. Great idea, though.

  47. linman says:

    WOW!!! It’s just the trick I’ve searched for. Thanks Dan!
    //linman from LW

  48. Crewcut says:

    It’s a slick solution, have been looking for something like this quite some time now :) Thanks alot Dan!
    But… I couldn’t resist to tweak it a bit for my own purposes (Microsoft Content Management Server) at the office.
    So this is what i did: Since everything always has to be finished yesterday, i dumped the thumbnail with the magnifying glass on it.
    Instead only 1, single image is used and with css I decide which part of the image has to be previewed to the audience. If you take a look in the source code you will see how the trick is done (you will be amazed how simple it is…).
    Anyway, I talk too much, go ahead and take a look
    Greetings from a chilly Amsterdam,

  49. tekp says:

    “I’ve only tested this on Mac: Camino, IE5.2 and Safari.”
    Works in firefox too. :D

  50. Dante says:

    Tested with Opera 7.23: works 100%.

  51. Anonymous says:

    Works fine in Safari!

  52. Daynah says:

    Dan, I love this article! The CSS method reminds me of this other article I read at A List Apart. CSS is amazing. :)

  53. Stu says:

    Nice idea, but I find it better to retain the original and produce the magnified version over the top of the text.
    This does not affect the flow of the page.
    and it works in IE.

  54. poolie says:

    i like the idea, and thanks for the link stu ;)

  55. Works in Opera 7.54 on Windows XP!

  56. Scott says:

    Dan, thanks for the inspiration. I’ve made a practical, easy-to-use zoom that includes a caption. Pure-CSS & XHTML-valid.
    Have a look.
    It uses one image file (with one image in it) for both views. You specify only the width parameter (not height) and you can do it from within the HTML code. You’ll also find a comparison of 7 zoom methods (yours included) with cut-n-paste CSS/HTML code.

  57. Great technique. I was already using the fast nav rollovers on our homepage, so when I was looking to create larger views of our products, I turned to the same technique and was glad to find this page. The reflow concerns addressed above are easily fixable. Just position your larger image absolutely, and arrange it from top and left based on the containing div. You get a great look, and don’t screw up your page’s style. Check out what I did here: http://www.harvardstudentagencies.com/shop/hsa_hbc_supplies_kits.aspx

  58. Nagaraj says:

    I have the problem with the zoom of span tag in Netscape and Mozilla. As in IE, netscape/mozilla not supporting the Zoom functionality for

  59. Rach says:

    wow!! i like it.. where do i get the code?