Lightbox3: Image Gallery Lightbox with Touch & Zoom Support

Category: Javascript , Modal & Popup | June 16, 2026
Authorlokesh
Last UpdateJune 16, 2026
LicenseMIT
Views0 views
Lightbox3: Image Gallery Lightbox with Touch & Zoom Support

The upgraded version of the legacy jQuery Lightbox2 plugin.

Lightbox3 is a vanilla JS lightbox library that helps you create a modern gallery lightbox with thumbnail links, full-size images, captions, swipe navigation, zoom gestures, and spring-based open and close animations.

The library keeps the familiar data-lightbox markup pattern from Lightbox2, but it removes the jQuery dependency. You can install it through npm for modern build tools or load the ESM build and stylesheet from a CDN.

Features:

  • Spring-physics open and close animations with configurable stiffness and damping.
  • Pinch-to-zoom, swipe navigation, and swipe-to-dismiss on touch devices.
  • Gallery grouping through the data-lightbox attribute.
  • Programmatic API for open, close, next, prev, and destroy.
  • CSS custom properties for backdrop, border radius, caption bar, and z-index.
  • Backward-compatible with Lightbox2 data-lightbox and data-title markup.

Use Cases:

  • Display a product image gallery on an e-commerce site.
  • Showcase a photography portfolio with captions and keyboard navigation.
  • Add an in-context lightbox to blog posts for full-size image viewing.

How To Use It:

Installation

Install Lightbox3 with NPM.

npm install lightbox3

Import the JavaScript module and the stylesheet in your app entry file.

import { Lightbox } from 'lightbox3';
import 'lightbox3/dist/lightbox3.css';
// Initialize once after your gallery markup exists in the DOM.
const productGalleryLightbox = Lightbox.init();

For a direct browser setup, load the stylesheet and import the ESM build from a CDN.

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/lightbox3.css">
<script type="module">
  import { Lightbox } from 'https://cdn.jsdelivr.net/npm/[email protected]/dist/lightbox3.esm.js';
  // Initialize after the module loads.
  Lightbox.init();
</script>

Create a basic image lightbox

Add data-lightbox to an anchor element. The anchor href should point to the full-size image, and the nested image can use a smaller thumbnail source.

<a href="/images/case-study-large.jpg" data-lightbox data-caption="Dashboard analytics preview">
  <img src="/images/case-study-thumb.jpg" alt="Dashboard analytics preview">
</a>
<script type="module">
  import { Lightbox } from 'https://cdn.jsdelivr.net/npm/[email protected]/dist/lightbox3.esm.js';
  // Attach Lightbox3 to every element that matches the default selector.
  Lightbox.init();
</script>

Create a gallery lightbox

<a href="/gallery/office-large.jpg" data-lightbox="studio-tour" data-caption="Office workspace">
  <img src="/gallery/office-thumb.jpg" alt="Office workspace">
</a>
<a href="/gallery/lounge-large.jpg" data-lightbox="studio-tour" data-caption="Team lounge">
  <img src="/gallery/lounge-thumb.jpg" alt="Team lounge">
</a>
<a href="/gallery/desk-large.jpg" data-lightbox="studio-tour" data-caption="Developer desk setup">
  <img src="/gallery/desk-thumb.jpg" alt="Developer desk setup">
</a>

A legacy Lightbox2 page may already use data-title for captions. Lightbox3 reads that attribute, so old caption markup can stay in place during migration.

<a href="/archive/event-stage-large.jpg" data-lightbox="event-2026" data-title="Main stage photo">
  <img src="/archive/event-stage-thumb.jpg" alt="Main stage photo">
</a>

Override the default CSS styles

  • --lb-backdrop-color: Sets the overlay backdrop color. The default value is rgba(0, 0, 0, 0.95).
  • --lb-image-border-radius: Sets the border radius of the opened image. The default value is 24px.
  • --lb-image-padding: Sets the space between the image and viewport edges. The default value is 40px.
  • --lb-chrome-bg: Sets the caption bar background color. The default value is rgba(24, 24, 24, 0.8).
  • --lb-chrome-text: Sets the caption bar text color. The default value is rgba(255, 255, 255, 0.9).
  • --lb-chrome-font-size: Sets the caption bar font size. The default value is 15px.
  • --lb-chrome-padding: Sets padding around the caption bar and navigation arrows. The default value is 16px.
  • --lb-chrome-border-radius: Sets the caption bar border radius. The default value is 48px.
  • --lb-z-index: Sets the overlay stacking level. The default value is 999999.
-root {
  --lb-backdrop-color: rgba(8, 10, 18, 0.96);
  --lb-image-border-radius: 16px;
  --lb-chrome-bg: rgba(12, 12, 12, 0.82);
  --lb-chrome-text: rgba(255, 255, 255, 0.92);
  --lb-chrome-font-size: 14px;
  --lb-z-index: 10000;
}

Custom trigger button

import { Lightbox } from 'lightbox3';
const mediaLightbox = Lightbox.init();
const openPreviewButton = document.querySelector('#open-floorplan-preview');
openPreviewButton.addEventListener('click', function () {
  // Open an image from a custom control.
  mediaLightbox.open('/media/floorplan-large.jpg', openPreviewButton);
});

All configuration options

  • selector (string): Sets the CSS selector for lightbox trigger elements. The default value is '[data-lightbox]'.
  • springOpen (SpringConfig): Controls the spring animation used during open and zoom-in transitions. The default value is { stiffness: 260, damping: 26 }.
  • springClose (SpringConfig): Controls the spring animation used during close and zoom-out transitions. The default value is { stiffness: 500, damping: 38 }.
  • padding (number): Sets the viewport padding around the opened image in pixels. The default value is 40.
  • debug (boolean): Shows a debug overlay with spring values and state information. The default value is false, and the ?debug URL parameter also enables it.

Available HTML Data Attributes

  • data-lightbox: Enables Lightbox3 on an anchor element. The anchor href provides the full-resolution image URL.
  • data-lightbox="name": Groups matching links into one gallery set.
  • data-caption="text": Adds caption text below the opened image.
  • data-title="text": Adds caption text through the Lightbox2-compatible caption attribute.
  • data-alt="text": Sets alt text for the full-size image. The thumbnail alt value acts as the fallback.

API Methods

const imageLightbox = Lightbox.init();
// Open a full-size image from JavaScript.
imageLightbox.open('/media/team-photo-large.jpg');
// Open a full-size image and use a trigger element for the morph animation.
const profileThumb = document.querySelector('.profile-card a[data-lightbox]');
imageLightbox.open('/media/profile-large.jpg', profileThumb);
// Close the active lightbox overlay.
imageLightbox.close();
// Move to the next image in the current gallery set.
imageLightbox.next();
// Move to the previous image in the current gallery set.
imageLightbox.prev();
// Remove event listeners, cancel animations, and tear down the instance.
imageLightbox.destroy();

Events

const imageLightbox = Lightbox.init();
// Fires when the open animation starts.
imageLightbox.on('open', function (event) {
  console.log('Lightbox opening:', event.detail);
});
// Fires when the open animation completes.
imageLightbox.on('opened', function (event) {
  console.log('Lightbox opened:', event.detail);
});
// Fires when the close animation starts.
imageLightbox.on('close', function (event) {
  console.log('Lightbox closing:', event.detail);
});
// Fires when the close animation completes and the overlay leaves the page.
imageLightbox.on('closed', function (event) {
  console.log('Lightbox closed:', event.detail);
});
// Fires when the active gallery image changes.
imageLightbox.on('navigate', function (event) {
  console.log('Gallery navigation:', event.detail);
});
// Fires when zoom-in starts from a tap or double-click.
imageLightbox.on('zoomIn', function (event) {
  console.log('Zoom in:', event.detail);
});
// Fires when zoom-out starts.
imageLightbox.on('zoomOut', function (event) {
  console.log('Zoom out:', event.detail);
});

Alternatives:

FAQs:

Q: How do I upgrade from Lightbox2 to Lightbox3 without changing my HTML?
A: Remove the jQuery and Lightbox2 script tags, then install Lightbox3 via npm or CDN. Your existing data-lightbox, data-lightbox="gallery", and data-title attributes work as they did before. Add the new CSS and JS files and call Lightbox.init().

Q: My data-title captions are not showing. What should I check?
A: Verify that the data-title attribute is on the <a> element, not on the <img>. Lightbox3 reads the attribute from the link.

Q: Can I open the lightbox programmatically without a trigger link on the page?
A: Yes. Call lb.open('image.jpg') without a second argument. The image will fade in without a morph animation. You can wire this to a button click or any custom logic.

Q: Why does my image open as a normal link instead of a lightbox?
A: Check that the anchor has data-lightbox, the JavaScript module loads correctly, and Lightbox.init() runs after the markup exists. Also confirm that the browser supports JavaScript modules when you use the CDN import path.

You Might Be Interested In:


Leave a Reply