A lightweight lightbox,
in a single file.

Zoom, pan, touch gestures, keyboard navigation, accessible labels — all packed into one dependency-free JavaScript file. CSS inlined, no build step, framework-agnostic.

6.9 KB min+gzip 0 dependencies 1 file MIT
See the demo

Quick start

Add the script, bind a selector, done.

<!-- Include (or download and self-host) -->
<script src="https://litezoom.dev/litezoom.min.js" defer></script>

<!-- Bind: article images open on click; full mode adds zoom / pan / thumbnails -->
<script>
  LiteZoom.bind('.post-content img', { mode: 'full' });
</script>
https://litezoom.dev/litezoom.min.js

Demo

This page uses LiteZoom itself — click any image. Scroll or pinch to zoom, drag to pan, pull down to close.

Keyboard: Esc close · switch · + zoom · double-click toggles 1x / 2x

Why LiteZoom

Trade-offs made for content sites, not a feature contest.

Single-file delivery

CSS inlined, SVG icons inline. No build chain, no peer dependencies — copy one file into any project and it works.

Two modes

simple just opens and switches, great for feeds; full adds zoom, pan, a thumbnail strip and captions for long-form articles.

Full gestures

Wheel and pinch zoom, drag to pan, swipe to switch, pull down to close — one Pointer Events implementation for desktop and touch.

Accessibility done right

Focus returns to the trigger on close; every aria label is localizable; respects prefers-reduced-motion.

Never hijacks real links

Images wrapped in links to other pages navigate as usual; links to large images load the hi-res original. Use data-litezoom for extension-less URLs.

Lazy-load enhancer

Ships enhance(): IntersectionObserver lazy loading + blur-in fade, sharing a single binding with the lightbox.

API

MethodDescription
LiteZoom.bind(sel, opts)Delegated binding: images matching sel open on click. opts.mode is 'simple' | 'full'; group(img) returns a group key for gallery navigation; caption(img) returns the caption; exclude(img) returns true to skip.
LiteZoom.open(items, i, opts)Open manually: items is an array of {src, thumb?, caption?}, i the start index. For React / Vue apps that handle clicks themselves.
LiteZoom.close()Close the current lightbox.
LiteZoom.enhance(sel, opts)Image enhancement: lazy loading (data-src) with blur-in fade; set opts.zoom to true to also bind the lightbox.
LiteZoom.refresh(root)Re-apply enhancement to images inserted dynamically.
data-litezoomExplicit marker, takes priority over the extension heuristic: on an <a> it means "the href is an image, open the lightbox" (for extension-less CDN URLs); as <img data-litezoom="hi-res URL"> it names the hi-res source directly, no wrapping link needed.
LiteZoom.labels(map)Override accessibility labels (Chinese by default): {viewer, prev, next, zoomIn, zoomOut, close, thumb(i)}.