liftbox

Navigation and gestures

Arrows, keyboard, swipe, transitions and the open and close animation.

Keyboard

KeyAction
ArrowRight / ArrowLeftNext / previous slide (previous / next in rtl)
Home / EndFirst / last slide
+ or = / -Zoom in / out by zoom.step
0Reset zoom, rotation and flip
EscapeClose
Tab / Shift+TabMove between the dialog's buttons, focus stays in

keyboard={false} turns off every shortcut above except Tab. Arrow keys, Home and End are left alone while a video, a form field or an editable element has focus. Keys that your own content already handled with event.preventDefault() are ignored.

Looping

loop is on by default, so the last slide wraps to the first. With loop={false} the arrows are disabled at both ends and dragging past an end meets resistance.

Live demo. Click a thumbnail to open it.

Gestures

Gestures use Pointer Events on the stage, so touch, pen and mouse all work. In right-to-left layouts, sideways drags and arrow keys are mirrored.

  • Drag sideways. The slide follows the pointer. Releasing past swipeThreshold (50px by default), or flicking faster than 0.5px per ms, changes slide.
  • Drag up or down. The image moves and shrinks and the backdrop fades. Releasing after 20% of the viewport height, or a flick projected past 40%, closes. Short taps never close.
  • Pinch to close. A pinch that starts at fit, never zooms in, and is released under 90% of the fitted size closes the viewer. Below fit the image follows the fingers instead of resisting, as the cue. A pinch that zoomed in first only settles back. pinchToClose={false} turns it off.
  • Zoomed in. A one-finger drag pans the image instead. See Zoom.
  • A drag never counts as a backdrop click.

Drags that start on a video, iframe, button, link, form field, role="slider" or anything inside [data-eg-no-gestures] are left to that element. swipe={false} turns gestures off.

Backdrop clicks

Clicking the empty area around the media closes the viewer. Set closeOnBackdropClick={false} to keep it open.

Transitions

<Lightbox transition="fade" {...props} />
ValueEffect
slideSlides sit side by side and move together. Dragging moves them under the finger.
fadeCross-fade between slides.
zoomThe incoming slide grows from 85% while the outgoing one fades.

Live demo. Click a thumbnail to open it.

All three animate transform and opacity only. Their length is --eg-duration and their curve is --eg-easing.

Open and close

The open animation flies the image out of the element returned by getThumbnail(index), scaled evenly so it covers that element and clipped to it, so a thumbnail cropped with object-fit: cover grows into the full image without a jump. Closing flies it back to the thumbnail of the slide on screen. When there is no thumbnail, or it is scrolled out of view, the image zooms from 92% and fades in instead.

onAfterOpen runs when the open animation ends. onAfterClose runs when the close animation ends and focus is back on the page.

Reduced motion

With prefers-reduced-motion: reduce, durations become zero. The lightbox opens, changes slide and closes at once.

Preloading

Only the current slide and preload slides on each side (2 by default) are mounted. Anything outside that window is not in the DOM and is never requested. The current image loads first; neighbors follow once it has, and on slow or Save-Data connections fewer of them are fetched. See Performance.

Edit this page on GitHub

On this page