A fully declarative lightbox. Add
data-wf-lightbox
to any trigger element and the JS handles the rest — no markup beyond the trigger is required. Supports
images
,
native video
(
.mp4
/
.webm
),
YouTube
,
Vimeo
, and
iframes
. The media type is detected automatically from the URL; use
data-wf-type
to force it.
Basic
Import the module once. All
[data-wf-lightbox]
triggers are wired automatically on
DOMContentLoaded
.
Give multiple triggers the same
data-wf-group
value to link them into a navigable gallery. Arrow buttons, keyboard left/right, and touch swipe all move between items. A counter-pill (2 / 6) shows the current position.
Set
data-wf-thumb
on each trigger (or include an
<img>
inside it) to populate the thumbnail strip at the bottom of the lightbox.
URLs ending in
.mp4
,
.webm
, or
.ogg
are detected automatically as native video. The video element gets
controls
,
autoplay
, and
playsinline
. Set
data-wf-type="video"
explicitly if the URL has no recognizable extension (e.g., a signed CDN URL).
<!-- Auto-detected from .mp4 extension -->
<a href="demo.mp4" data-wf-lightbox data-wf-caption="Product demo">
Watch demo
</a>
<!-- Forced type (signed CDN URL without extension) -->
<a href="https://cdn.example.com/video?token=xyz"
data-wf-lightbox data-wf-type="video">
Watch video
</a>
YouTube
YouTube URLs are auto-detected. Short (
youtu.be/
), full (
youtube.com/watch?v=
), and embed (
youtube.com/embed/
) formats all work. The video ID is extracted and the player is embedded via the YouTube iframe API with
autoplay=1
.
Vimeo URLs (
vimeo.com/<id>
or
vimeo.com/video/<id>
) are auto-detected. The video ID is extracted and the player is embedded via the Vimeo iframe API with
autoplay=1
.
<!-- Standard Vimeo URL -->
<a href="https://vimeo.com/123456789" data-wf-lightbox>Watch</a>
<!-- /video/ form also works -->
<a href="https://vimeo.com/video/123456789" data-wf-lightbox>Watch</a>
Iframe
Set
data-wf-type="iframe"
to load any URL in an embedded frame. The default frame is
min(92vw, 1000px)
wide and
min(80dvh, 660px)
tall. Override with
data-wf-width
and
data-wf-height
(values in px, no unit suffix needed).
Add the class
wf-lightbox-play
to a trigger wrapper to overlay a CSS-only play button on the thumbnail. Useful for video gallery cards where the thumbnail image should visually signal that clicking opens a video rather than a photo.
Overlay background color. Also receives a backdrop-filter: blur(6px) effect.
--wf-lightbox-btn-size
2.75rem
Width and height of the close, previous, and next buttons.
--wf-lightbox-radius
var(--wf-radius-5)
Border radius of the media frame, images, videos, and iframes.
--wf-lightbox-caption-bg
rgba(0,0,0,0.55)
Background of the caption bar that appears beneath the media.
Programmatic API
The static
WojoLightbox.open()
and
WojoLightbox.close()
methods let you control the lightbox from JavaScript without any trigger element in the DOM.
JS
import { WojoLightbox } from './wf-lightbox.js'
// Open a single image
WojoLightbox.open({
src: 'photo.jpg',
type: 'image',
caption: 'My caption',
})
// Open a YouTube video
WojoLightbox.open({
src: 'https://youtu.be/dQw4w9WgXcQ',
type: 'youtube',
})
// Close from outside
WojoLightbox.close()
Method
Description
WojoLightbox.open(item)
Open the lightbox with an arbitrary item object. Properties: src, type, caption, thumb, width, height. Closes any currently open lightbox first.
WojoLightbox.close()
Close the currently open lightbox with the normal fade-out animation.
Events
Events are dispatched on the
trigger element
that opened the lightbox and bubble up the DOM. When opened via
WojoLightbox.open()
no trigger element is involved, so no events are fired.
JS
document.addEventListener('wf:lightbox-open', e => {
console.log('Opened:', e.detail.src, e.detail.type)
console.log('Trigger element:', e.detail.trigger)
})
document.addEventListener('wf:lightbox-close', () => {
console.log('Lightbox closed')
})
document.addEventListener('wf:lightbox-change', e => {
console.log(`Gallery: ${e.detail.index + 1} of ${e.detail.total}`)
})
Event
detail
Fired when
wf:lightbox-open
{ trigger, src, type }
The lightbox opens. trigger is the clicked element; src and type are the resolved media values.
wf:lightbox-close
—
The lightbox finishes its close animation and is removed from the DOM.
wf:lightbox-change
{ index, total }
The gallery navigates to a different item. index is 0-based; total is the gallery size.
Class Reference
All overlay classes below are created and injected into
<body>
by the JS at open time and removed on close. The only class you add yourself is
wf-lightbox-play
on trigger wrappers.
Class
Description
wf-lightbox-overlay
Fixed the full-viewport overlay. Has role="dialog" and aria-modal="true". Receives wf-lb-closing during the close animation.
wf-lightbox-stage
Content stage containing the frame, caption, and thumbnail strip. Receives wf-lb-slide-next or wf-lb-slide-prev during gallery navigation to trigger the slide animation.
wf-lightbox-frame
Media frame. Contains the <img>, <video>, <iframe>, or video wrapper depending on media type.
wf-lightbox-video-wrap
16:9 responsive wrapper inserted around YouTube and Vimeo iframes.
wf-lightbox-spinner
Spinning loader shown inside the frame while media is loading. Removed on load / canplay.
wf-lightbox-caption
Caption bar rendered below the frame. Hidden when no caption is set.
wf-lightbox-counter
Pill showing current position in a gallery (e.g. “2 / 5”). Hidden for single items.
wf-lightbox-close
Close button, fixed top-right. Focuses automatically on open for keyboard accessibility.
wf-lightbox-prev
Previous arrow button, fixed left. Hidden for single items.
wf-lightbox-next
Next arrow button, fixed right. Hidden for single items.
wf-lightbox-thumbs
Thumbnail strip container below the stage. Hidden when the gallery has fewer than two items or no items provide a thumb.
wf-lightbox-thumb
Individual thumbnail in the strip. Receives wf-lb-thumb-active for the currently displayed item.
wf-lb-thumb-active
State class on the active gallery thumbnail.
wf-lightbox-play
Add to a trigger’s wrapper element to overlay a CSS-only circular play button on its thumbnail. No JS required.
wf-lb-closing
State class is added to the overlay during the close animation. Removed when the overlay is destroyed.
wf-lb-slide-next / wf-lb-slide-prev
Applied to .wf-lightbox-stage during gallery navigation to trigger the slide-in animation.