Magnifying Glass
A round lens follows the mouse, a finger or the arrow keys and shows your own image magnified twice, high-resolution file included.
Updated
This effect is part of Effect.Labs — 840 vanilla effects, some free, some premium. Gallery has 44 effects, including 6 free. Explore the category →
3 usage examples



How it works
The .mgl-frame holds a real <img class="mgl-image"> tag and an empty disc, .mgl-lens. When the lens opens, the script uses the image itself as its background, or the file named in data-zoom-src if you supply a larger one. Swap the photo in the HTML and the lens follows: nothing is copied into the JavaScript.
On every move, the script redoes the object-fit: cover crop (same scale, same offset as the visible photo), multiplies it by data-zoom (2 by default) and positions the background so the target point sits in the middle of the disc. The lens may overflow the frame; the frame's rounded edge clips it cleanly.
The script finds every .fx-0180-root on the page and wires each one separately: two magnifiers on one page do not interfere, and pasting the script twice breaks nothing. The frame takes the available width up to --mgl-width (280 px) and keeps the shape set by --mgl-ratio.
Accessibility
- Keyboard: the frame takes Tab focus and the lens opens in the middle (then, next times, where it was last); arrow keys move it by 12 px (48 px with Shift) and Escape closes it.
- Touch: putting a finger down opens the lens there, dragging moves it, lifting the finger closes it, a single tap included. The frame blocks page scrolling during the gesture (
touch-action: none); the page scrolls from the rest of the screen. - Screen readers: the frame is a group named by its
aria-labeland the image keeps its alt text; the lens and caption are hidden (aria-hidden), since they show nothing more than the image. - Reduced motion: under
prefers-reduced-motion: reduce, the lens appears without a fade; it still follows the pointer, because the user is the one moving it.
Browser compatibility
Pointer Events, object-fit, aspect-ratio and about 3.5 KB of JavaScript, no dependency. Measured in Chromium 151, Firefox 153 and WebKit 26.5: lens over a red image swapped in by the buyer (the lens shows the red), two independent copies, script pasted twice without error, Tab and arrow keys, a real finger at 390 px (Chromium), no overflow.
Without JavaScript, the image shows on its own, without a lens. Before Safari 15 and Chrome 88 (no aspect-ratio), the frame takes the height of the image itself; the zoom stays exact because it is computed from the frame's real size.
The code
HTML structure to paste into your page (the CSS + JS come with your purchase):
<div class="fx-0180-root">
<div class="mgl-frame" tabindex="0" role="group" aria-label="Magnifier: hover the image, drag a finger or use the arrow keys" data-zoom="2">
<img class="mgl-image" src="your-photo.jpg" data-zoom-src="your-photo-large.jpg" alt="Photo description">
<span class="mgl-label" aria-hidden="true">Move Mouse</span>
<div class="mgl-lens" aria-hidden="true"></div>
</div>
</div>
One-time payment, no subscription — the code is yours forever
Customize
Options passed to the API or data-* attributes:
| Option / property | Default | Effect |
|---|---|---|
Image (HTML — src of .mgl-image) |
violet grid pattern (inline SVG) | Put in your photo and its alt text. Add data-zoom-src on the same tag so the lens shows a larger, sharper file than the displayed image (same framing). |
data-zoom (on .mgl-frame) |
2 | Magnification inside the lens. 3 to 4 for printed text or a map, 1.5 for a product photo. |
--mgl-size |
100px | Lens diameter (or side). |
--mgl-shape |
50% | Lens rounding: 50% for a disc, 0 or a few pixels for a square lens. |
--mgl-ring |
3px solid #fff | Lens border, to match your brand. |
--mgl-width · --mgl-ratio · --mgl-radius |
280px · 7 / 5 · 0.75rem | Maximum frame width (it shrinks on small screens), proportions and rounding. 100% for a full-width image. |
.mgl-label caption |
“Move Mouse” | Text laid in the middle of the image. Delete the <span> on a real photo. |
FAQ
<img> tag (or data-zoom-src) when the lens opens. If you change the photo by script, the lens follows as soon as the new image has loaded.data-zoom-src.--mgl-shape: 0 (or 4px to soften the corners) on the root. The zoom maths stay the same; only the disc's shape changes.