Image Magnifier Lens on Hover
Shows a round magnifying lens over chosen images as visitors move the mouse across them, using the largest version of the image available. Opt in per image with a CSS class.
Opens WPIDE on
Code
<style>
.wpide-magnifier-lens {
position: fixed;
z-index: 99999;
display: none;
border: 3px solid #fff;
border-radius: 50%;
background-color: #fff;
background-repeat: no-repeat;
box-shadow: 0 4px 16px rgba(0, 0, 0, .35);
pointer-events: none;
}
@media (hover: hover) and (pointer: fine) {
.wpide-magnify img,
img.wpide-magnify {
cursor: zoom-in;
}
}
</style>
<script>
(function () {
var ZOOM = 2.5; // Magnification.
var LENS_SIZE = 180; // Lens diameter, in pixels.
var images = document.querySelectorAll('.wpide-magnify img, img.wpide-magnify');
if (!images.length || !window.PointerEvent) {
return;
}
var lens = document.createElement('div');
lens.className = 'wpide-magnifier-lens';
lens.setAttribute('aria-hidden', 'true');
lens.style.width = LENS_SIZE + 'px';
lens.style.height = LENS_SIZE + 'px';
document.body.appendChild(lens);
function hide() {
lens.style.display = 'none';
}
// Use the biggest version available: a link to the image file, data-full-url or the largest srcset entry.
function fullSource(img) {
var link = img.closest('a[href]');
if (link && /\.(jpe?g|png|gif|webp|avif)(\?.*)?$/i.test(link.href)) {
return link.href;
}
if (img.getAttribute('data-full-url')) {
return img.getAttribute('data-full-url');
}
var best = img.currentSrc || img.src;
var bestWidth = 0;
(img.getAttribute('srcset') || '').split(',').forEach(function (candidate) {
var parts = candidate.trim().split(/\s+/);
var width = parseInt(parts[1], 10) || 0;
if (parts[0] && width > bestWidth) {
bestWidth = width;
best = parts[0];
}
});
return best;
}
Array.prototype.forEach.call(images, function (img) {
var source = '';
function move(event) {
var rect = img.getBoundingClientRect();
var x = event.clientX - rect.left;
var y = event.clientY - rect.top;
var half = LENS_SIZE / 2;
if (x < 0 || y < 0 || x > rect.width || y > rect.height) {
hide();
return;
}
lens.style.left = (event.clientX - half) + 'px';
lens.style.top = (event.clientY - half) + 'px';
lens.style.backgroundSize = (rect.width * ZOOM) + 'px ' + (rect.height * ZOOM) + 'px';
lens.style.backgroundPosition = (half - x * ZOOM) + 'px ' + (half - y * ZOOM) + 'px';
lens.style.display = 'block';
}
// Only a mouse shows the lens. Touch, pen and keyboard use the image as normal.
img.addEventListener('pointerenter', function (event) {
if (event.pointerType !== 'mouse') {
return;
}
if (!source) {
source = fullSource(img);
}
lens.style.backgroundImage = 'url("' + source.replace(/"/g, '%22') + '")';
move(event);
});
img.addEventListener('pointermove', function (event) {
if (event.pointerType === 'mouse') {
move(event);
}
});
img.addEventListener('pointerleave', hide);
});
window.addEventListener('scroll', hide, { passive: true });
document.addEventListener('keydown', function (event) {
if (event.key === 'Escape') {
hide();
}
});
})();
</script>
Notes
Add wpide-magnify under Advanced > Additional CSS class(es) of an Image or Gallery block, or to any img tag. The lens only appears for a mouse; on touch screens and with the keyboard the image behaves as usual, and a link to the full-size file still works. Change ZOOM and LENS_SIZE at the top of the script.
How to add this snippet
- Install WPIDE on your WordPress site (it is free) and open Code Snippets.
- Use snippet above adds it from the library in one click. Or copy the code into a new snippet with the same code type.
- It is added inactive: review the code and settings, then switch it on.