I first created a Proof-of-Concept to get a feel for how to do it. You can see a live demo here. I’ve added comments to the code so feel free to take a look. The main goal was to see if I could successfully track the mouse position over the image. I created a “lens” around the cursor and used
backdrop-filter to covert parts of the image to greyscale.
Mimic a Magnifying Lens
Since I already had a movable lens why not have it display the full-size version of the portion of the image it was over. The easiest way to do this was to use the full-size image as the lens’
background-image and update the
background-position based on the mouse location relative to the thumbnail. This is where I had to put on my Math hat. It took a bit of doing but wasn’t difficult. Live demo here.
While novel, I’m not so sure if it’s usable. Granted, I made the lens quite small in my demo but it gives the user some context for the area being magnified.
Use an overlay, why not?
I finally decided to create the version I remember seeing most often: replacing the thumbnail with a full-sized zoom. It was a simple task to enlarge the lens from the previous example, position it over the thumbnail and using the
opacity property to display it only when the user hovers over the image. Add a transition to make the change less jarring and there you go. A live demo for you.
I realize that we could completely remove the lens/overlay and instead have the full-size as the
background-image for the thumbnail wrapper. Hide the thumbnail on hover and re-position the background in the same way we’ve done before.
I’m still not sure about the user-experience of these “Zoom on hover” images. Part of me feels that it would be better to have a separate area to display the magnified view rather than placing it over the thumbnail (or replacing it outright). It’s quite trivial to implement this and I’ll leave that up to the you to try out in your own time. In the meantime you can download all these files here.
Edit (14 Apr 2023) Forgot to mention that it isn’t quite as smooth on mobile and touch devices yet. Perhaps that’s something I’ll look into next time…