Enhancement

Lightbox

Image gallery viewer shown in a native modal dialog

Import
@parallelogram-js/core/components/Lightbox
Selector
[data-lightbox]
Stylesheet
@parallelogram-js/core/styles/lightbox.css

Playground

About

Links that share a data-lightbox gallery name open one viewer. It is named "Image viewer", takes focus on its close button, keeps the rest of the page inert and returns focus to the link when it closes. The arrow keys move between images, Escape and the backdrop close it, the counter is announced as it changes, and slides are skipped when the user prefers reduced motion.

Each link's href is the full-size image, so without JavaScript the links still open the images.

Usage

Register the component and the framework loads it the first time a page contains [data-lightbox].

import { Parallelogram } from '@parallelogram-js/core';

const app = Parallelogram.create();
app.components.add('[data-lightbox]', () => import('@parallelogram-js/core/components/Lightbox'));
app.run();

The framework is optional. Lightbox.enhanceAll() mounts the component on every matching element by itself, for a page that wants one enhancement rather than a framework:

import Lightbox from '@parallelogram-js/core/components/Lightbox';

Lightbox.enhanceAll();

It takes a selector and the component's options, and returns the instance it mounted them with. What it leaves out is what the framework adds: loading a component only on the pages that use it, mounting again after a page swap, and ordering with dependsOn.

Its styles come from the package stylesheet:

@import '@parallelogram-js/core/styles/lightbox.css';

Attributes

NameTypeDefaultDescription
data-lightboxrequiredstringnoneThe gallery name; links with the same name browse together On a link to the full-size image.
data-lightbox-srcsetstringnoneA source set for the full-size image
data-lightbox-sizesstringnoneSizes for the source set (default 100vw)
data-lightbox-close-escapebooleantrueClose with Escape. When false, a second Escape without a click or other key press in between still closes the viewer, because browsers don't let a page keep a modal dialog open against it For every instance, Lightbox.defaults.closeOnEscape.
data-lightbox-close-backdropbooleantrueClose when the backdrop is clicked For every instance, Lightbox.defaults.closeOnBackdrop.
data-lightbox-show-counterbooleantrueShow the image count, such as 2 of 5 For every instance, Lightbox.defaults.showCounter.
data-lightbox-show-navbooleantrueShow the previous and next buttons For every instance, Lightbox.defaults.showNavigation.
data-lightbox-key-navbooleantrueMove between images with the arrow keys For every instance, Lightbox.defaults.keyNavigation.
data-lightbox-directional-transitionsbooleantrueSlide images in the direction of travel For every instance, Lightbox.defaults.useDirectionalTransitions.
data-lightbox-preloadadjacent | all | noneadjacentWhich images to load ahead of time For every instance, Lightbox.defaults.preloadStrategy.
data-lightbox-viewer-labelstringImage viewerThe accessible name of the viewer For every instance, Lightbox.defaults.viewerLabel.
data-lightbox-close-labelstringCloseThe accessible name of the close button For every instance, Lightbox.defaults.closeLabel.
data-lightbox-prev-labelstringPrevious imageThe accessible name of the previous button For every instance, Lightbox.defaults.prevLabel.
data-lightbox-next-labelstringNext imageThe accessible name of the next button For every instance, Lightbox.defaults.nextLabel.
data-lightbox-load-errorstring{image} couldn't be loadedShown in place of an image that fails to load, with {image} for the thumbnail's alt text For every instance, Lightbox.defaults.loadError.
data-lightbox-load-error-untitledstringThe image couldn't be loadedThe same message for an image whose thumbnail has no alt text For every instance, Lightbox.defaults.loadErrorUntitled.
data-lightbox-base-classstringlightboxClass on the viewer For every instance, Lightbox.defaults.baseClass.
data-lightbox-overlay-classstringlightbox__overlayClass on the dialog For every instance, Lightbox.defaults.overlayClass.
data-lightbox-container-classstringlightbox__containerClass on the inner container For every instance, Lightbox.defaults.containerClass.
data-lightbox-close-classstringlightbox__closeClass on the close button For every instance, Lightbox.defaults.closeClass.
data-lightbox-prev-classstringlightbox__nav lightbox__nav--prevClasses on the previous button For every instance, Lightbox.defaults.prevClass.
data-lightbox-next-classstringlightbox__nav lightbox__nav--nextClasses on the next button For every instance, Lightbox.defaults.nextClass.
data-lightbox-content-classstringlightbox__contentClass on the image area For every instance, Lightbox.defaults.contentClass.
data-lightbox-image-classstringlightbox__imageClass on the image For every instance, Lightbox.defaults.imageClass.
data-lightbox-counter-classstringlightbox__counterClass on the counter For every instance, Lightbox.defaults.counterClass.
data-lightbox-state-opening-classstringis-openingClass on the viewer while opening For every instance, Lightbox.defaults.stateOpeningClass.
data-lightbox-state-open-classstringis-openClass on the viewer while open For every instance, Lightbox.defaults.stateOpenClass.
data-lightbox-state-transitioning-classstringis-transitioningClass on the viewer while changing image For every instance, Lightbox.defaults.stateTransitioningClass.
data-lightbox-state-closing-classstringis-closingClass on the viewer while closing For every instance, Lightbox.defaults.stateClosingClass.
data-lightbox-show-classstringshowClass on a shown element For every instance, Lightbox.defaults.showClass.
data-lightbox-slide-left-classstringslide-leftClass for a slide to the left For every instance, Lightbox.defaults.slideLeftClass.
data-lightbox-slide-right-classstringslide-rightClass for a slide to the right For every instance, Lightbox.defaults.slideRightClass.
data-lightbox-stateset by the componentclosed | opening | open | transitioning | closingnoneThe viewer's state On the viewer.

Events

NameDetailDescription
lightbox:mounted{ element: HTMLElement; gallery: string }A gallery link was set up Event bus
lightbox:opened{ gallery: string; index: number; total: number }The viewer opened Event bus
lightbox:closedRecord<string, never>The viewer closed Event bus
lightbox:stateChange{ element: HTMLElement; oldState: string; newState: string; gallery: string }The viewer's state changed Event bus

CSS custom properties

NameDefaultDescription
--lightbox-transition-durationnoneLength of the open, close and slide animations
--lightbox-transition-easingnoneEasing of the animations
--lightbox-overlay-bgrgba(0, 0, 0, 0.9)Background of the viewer, dark in both themes so it doesn't follow the page
--lightbox-colorwhiteColour of the buttons, counter, error message and focus outlines
--lightbox-close-bgtransparentClose button background
--lightbox-close-hover-bgtransparentClose button background on hover
--lightbox-nav-bgrgba(0, 0, 0, 0.5)Previous and next button background
--lightbox-nav-hover-bgrgba(0, 0, 0, 0.7)Previous and next button background on hover
--lightbox-counter-bgrgba(0, 0, 0, 0.7)Counter background