a-lightbox
A slot-based image lightbox element with built-in overlay behavior and shared image transitions via the View Transitions API.
The a-lightbox element turns a trigger image into a modal image viewer. It owns the overlay state, scroll locking, focus management, Escape handling, and the transition between the trigger image and the enlarged image.
Featured example
<a-lightbox>
<button slot="trigger" type="button">
<img src="/images/thumb.jpg" alt="Gallery preview" />
</button>
<div slot="content">
<img src="/images/large.jpg" alt="Gallery preview" />
</div>
<button slot="close" type="button">
Close
</button>
</a-lightbox>
The element requires an <img> in the trigger slot and an <img> in the content slot. It uses those two images as the shared transition endpoints.
Accessibility features
- Focus moves into the lightbox when it opens and returns to the previously focused element when it closes.
- Pressing
Escapecloses the overlay. - The overlay uses
role="dialog"andaria-modal="true". - The trigger receives
aria-haspopup="dialog"and an updatedaria-expandedstate. - The trigger image and enlarged image should use meaningful
alttext when the image content is important.
How to use it with examples
Programmatic control
import "@sv/elements/lightbox";
const lightbox = document.querySelector("a-lightbox");
await lightbox.show();
await lightbox.hide();
lightbox.toggle();
Styling slotted content
[slot="content"] img {
max-width: 96vw;
max-height: 96vh;
object-fit: contain;
}
[slot="close"] button {
border-radius: 0.5rem;
background: rgb(255 255 255 / 0.9);
padding: 0.5rem 0.75rem;
}
Using custom close content
<a-lightbox>
<button slot="trigger" type="button">
<img src="/thumb.jpg" alt="Preview" />
</button>
<div slot="content">
<img src="/large.jpg" alt="Preview" />
</div>
<div slot="close">
<button type="button" aria-label="Close image viewer">
<svg viewBox="0 0 24 24" aria-hidden="true"><!-- icon --></svg>
</button>
</div>
</a-lightbox>
Customization options
- Use the
trigger,content, andcloseslots to provide your own markup. - Style the trigger, content, and close markup directly in the nodes you pass into those slots.
- Call
show(),hide(), ortoggle()for programmatic control. - The element requires
document.startViewTransition(). It throws instead of falling back when the API is unavailable.
Type Documentation
Lightbox
Attributes
| Name | Type | Default value | Description |
|---|
Methods
Lightbox.bindTriggerClickListeners()
src/Lightbox.ts:312
Lightbox.clearTransitionNames(triggerImage: HTMLImageElement, contentImage: HTMLImageElement, finished: Promise)
src/Lightbox.ts:380
Lightbox.firstUpdated()
src/Lightbox.ts:112
Invoked when the element is first updated. Implement to perform one time work on the element after update.
firstUpdated() {
this.renderRoot.getElementById('my-text-area').focus();
}Setting properties inside this method will trigger the element to update again after this update cycle completes.
Lightbox.hide()
src/Lightbox.ts:275
Lightbox.matchesAssignedPath(path: EventTarget[], elements: Element[])
src/Lightbox.ts:355
Lightbox.moveElements(elements: Element[], mount: undefined | Element, label: string)
src/Lightbox.ts:323
Lightbox.onBlurExit(event: Event)
src/Lightbox.ts:160
Lightbox.onStageClick(event: MouseEvent)
src/Lightbox.ts:169
Lightbox.onTriggerSlotChange()
src/Lightbox.ts:155
Lightbox.prepareTransition()
src/Lightbox.ts:434
Lightbox.render()
src/Lightbox.ts:131
Invoked on each update to perform rendering tasks. This method may return any value renderable by lit-html's
- typically a
. Setting properties inside this method will not trigger the element to update.
Lightbox.requireBlur()
src/Lightbox.ts:372
Lightbox.requireImage(elements: Element[], slot: string)
src/Lightbox.ts:340
Lightbox.requireStartViewTransition()
src/Lightbox.ts:364
Lightbox.restoreElements(elements: Element[], slot: string)
src/Lightbox.ts:333
Lightbox.restoreStructure()
src/Lightbox.ts:231
Lightbox.runHide()
src/Lightbox.ts:279
Lightbox.runShow()
src/Lightbox.ts:247
Lightbox.runTransition(target: boolean, transition: () => Promise)
src/Lightbox.ts:403
Lightbox.show()
src/Lightbox.ts:243
Lightbox.swapTransitionNames(from: HTMLImageElement, to: HTMLImageElement)
src/Lightbox.ts:398
Lightbox.syncStructure()
src/Lightbox.ts:214
Lightbox.syncTriggerAttributes()
src/Lightbox.ts:236
Lightbox.toggle()
src/Lightbox.ts:303
Lightbox.updated(changed: Map)
src/Lightbox.ts:123
Invoked whenever the element is updated. Implement to perform post-updating tasks via DOM APIs, for example, focusing an element.
Setting properties inside this method will trigger the element to update again after this update cycle completes.