Pan Zoom
Your image stays enlarged one and a half times inside its frame; the mouse, a finger or the arrow keys pick the visible part, and it recentres when you leave.
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 <img class="pnz-image"> is permanently enlarged by transform: scale(var(--pnz-scale)) (1.5) and the .pnz-frame clips the overflow. Only part of the image shows at a time, the centre at rest.
The script only changes the origin of that enlargement (transform-origin). Under the mouse or finger it works out the position as a percentage of the frame and uses it as the origin: the hovered corner of the image comes to the matching edge of the frame, which feels like moving the photo around. A --pnz-follow transition (0.1 s) smooths the tracking. When you leave the frame, the origin returns to 50% 50%.
Each .fx-0182-root on the page gets its own wiring, with no fixed id: two frames never drive each other and pasting the script twice has no side effect. The frame follows the available width up to --pnz-width.
Accessibility
- Keyboard: the frame takes Tab focus; arrow keys shift the visible area by 5% of the image (20% with Shift), Escape or leaving the frame recentres it.
- Touch: dragging a finger over the image explores it; the frame holds back page scrolling during the gesture (
touch-action: none). Lifting the finger recentres the image. - Screen readers: the frame is a named group and the image keeps its alt text; the enlargement removes nothing from what is read.
- Reduced motion: under
prefers-reduced-motion: reduce, the visible area jumps straight to the target point, without sliding.
Browser compatibility
CSS transforms, Pointer Events, aspect-ratio and 2 KB of JavaScript, no dependency. Measured in Chromium 151, Firefox 153 and WebKit 26.5: two independent copies, script pasted twice without error, arrow keys, a real finger at 390 px in Chromium, no overflow.
Without JavaScript, the image stays enlarged and centred, with no exploring. Without aspect-ratio (before Chrome 88 and Safari 15), the frame takes the image's natural height.
The code
HTML structure to paste into your page (the CSS + JS come with your purchase):
<div class="fx-0182-root">
<div class="pnz-frame" tabindex="0" role="group" aria-label="Enlarged image: hover it, drag a finger or use the arrow keys to explore it">
<img class="pnz-image" src="your-photo.jpg" alt="Photo description">
<span class="pnz-label" aria-hidden="true">Pan Around</span>
</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 .pnz-image) |
violet grid pattern (inline SVG) | Your photo and its alt. Use a file at least --pnz-scale times wider than the frame to keep it sharp. |
--pnz-scale |
1.5 | Permanent enlargement. 1.2 for a gentle move, 2 or more to read a detail. |
--pnz-follow |
0.1s | How long the view takes to reach the target point; 0s for crisp tracking, 0.3s for a slower glide. |
--pnz-width · --pnz-ratio · --pnz-radius |
280px · 7 / 5 · 0.75rem | Maximum width, proportions and rounding of the frame; 100% for a full-width image. |
.pnz-label caption |
“Pan Around” | Text centred on the image; delete it on a real photo. |
touch-action (.pnz-frame rule) |
none | Switch to pan-y if the image is very tall on mobile: the page will scroll vertically and finger exploring happens by sliding sideways. |
FAQ
pointerleave listener from the script to keep the last position.--pnz-width: 100% and your image's proportions in --pnz-ratio. The maths use percentages of the frame, so its real size does not matter.