Lightbox
Full-screen media lightbox with carousel navigation
Source
LLM docs
Docs
Package
License
Installation
After installation import package styles at the root of your application:
Usage
@mantine/lightbox is a full-screen media lightbox built on embla carousel.
Click any image to open the lightbox:





Slide data
The slides prop accepts an array of LightboxSlideData objects. There are three slide types –
image (default), video and custom:
Image loading
All slides are mounted at once, so images are loaded lazily by default – only the active slide uses
loading="eager", every other slide uses loading="lazy" and is downloaded by the browser as it
comes into view. This way opening a gallery with a large number of slides does not start a download
for every image at once. Thumbnails are always lazy – note that thumbSrc falls back to src, so
set it to a smaller image if the originals are large.
Set the loading property on an image slide to override this per slide, for example to eagerly
preload the slide next to the one that is opened first:
Navigation and close behavior
Use the following props to control built-in interactions:
withNavigation– shows previous/next arrow buttons,trueby defaultloop– enables infinite loop navigation,falseby defaultcloseOnClickOutside– closes the lightbox when the empty space around the slide content is clicked,falseby defaultcloseOnSwipeDown– closes the lightbox on mobile swipe down,trueby defaultwithKeyboardEvents– enables keyboard shortcuts (arrows,F/T/Z),trueby default;Escapealways closes the lightboxreturnFocus– returns focus to the last active element when the lightbox is closed,trueby defaultwithInitialFocusPlaceholder– adds a hidden focusable element at the start of the lightbox content so that the first toolbar button does not receive visible focus when the lightbox is opened with a pointer,trueby default
Zoom
Enable image zoom with the withZoom prop. On desktop, click an image to zoom in, scroll wheel to
adjust zoom level, and drag or use arrow keys to pan when zoomed. On mobile, double-tap to zoom and
pinch to adjust. Use zoomMaxScale to change the maximum zoom scale (3 by default):





Click image to zoom, scroll to adjust, drag to pan when zoomed. Press Z to toggle zoom via keyboard.
Thumbnails
Enable the bottom thumbnail strip with withThumbnails. Click a thumbnail to navigate to that slide.
Toggle visibility at runtime with the T keyboard shortcut or the toolbar button – the strip is
animated with the transitionDuration prop value:





All features
Combine withZoom, withThumbnails, withFullscreen, and withDownload for the full experience:





Loop navigation
Set loop to enable infinite wrapping at the ends of the slide list:
Slide transition
By default, programmatic navigation (arrow buttons, keyboard, controlled index changes) snaps
instantly. Set withSlideTransition to animate slide changes. The animation is handled by embla –
use emblaOptions={{ duration: 40 }} to change its speed (embla duration is not in milliseconds,
values between 20 and 60 are recommended):
Embla options
The carousel behavior can be customized with the emblaOptions prop – it is passed directly to the
underlying embla carousel instance. For example, you
can change drag behavior or scroll animation speed.
loop and startIndex are managed by the loop and currentIndex props and cannot be set through
emblaOptions. A watchDrag callback is still called, but dragging is always disabled while the
image is zoomed, so the zoom gesture is not interrupted:
z-index
zIndex controls the z-index of the overlay and the content elements, 400 by default:
Open and close transition
By default, the overlay fades in and the content pops in – it is scaled from 95% to 100% while
fading. Use transitionProps to change the animation of the content – the overlay always fades.
transitionProps accepts the same options as the Transition component
(transition, duration, timingFunction). Use transitionDuration as a shorthand to change only
the duration (200 by default):
Disable animations
Set transitionProps={{ duration: 0 }} to open and close the lightbox instantly, without any
animation:
Swipe to close
On mobile, swiping down closes the lightbox. This is enabled by default.
Set closeOnSwipeDown={false} to disable:
Click outside to close
Set closeOnClickOutside to close the lightbox when the empty space around the current slide
content is clicked – clicks on the image, video or any custom slide content are ignored, as well as
clicks on the toolbar, navigation buttons, caption and thumbnails. The option is disabled by default
to prevent accidental closing:
Store API
Mount Lightbox.Provider once in your app and open the lightbox from anywhere
using the static Lightbox methods (aliases of the default lightbox store actions):
Multiple lightboxes
By default, Lightbox.Provider and the static Lightbox.open/close/next/prev/setIndex methods
use the shared lightboxStore. To run several independent lightboxes, create an isolated store
with actions bound to it using createLightbox and pass the store to the store prop:
To subscribe to the state of any lightbox store in a component, use the useLightboxStore hook:
Video slides
Set type: 'video' on a slide to render a <video> element. Videos are automatically
paused when navigating away from the slide:
Opens on a video slide with autoPlay. Navigate away to see the video pause automatically.
Custom slides
Set type: 'custom' with a render function for fully custom slide content.
Use renderThumb to customize the thumbnail as well:
Custom toolbar
Override the default toolbar items with the toolbarItems prop. Each item has
a key, icon, label, onClick, and optional position ('left' or 'right').
toolbarItems can be either an array or a function that receives the current lightbox state and
handlers – use the function form to build items that depend on the internal state, for example
the thumbnails, fullscreen and zoom toggles. The function receives the following payload:
Use the built-in toolbar item factories for common actions:
Compound components
For full layout control, compose sub-components directly:
Note that Lightbox.Thumbnails renders only when withThumbnails is set on Lightbox.Root.
Available sub-components:
Lightbox.Root— overlay, portal, focus trap, scroll lock, keyboard handlingLightbox.Toolbar— top bar with actions and slide counterLightbox.Slides— Embla carousel wrapperLightbox.Slide— individual slide (image, video, or custom)Lightbox.Thumbnails— bottom thumbnail stripLightbox.Navigation— prev/next arrow buttonsLightbox.Caption— text below the active slideLightbox.CloseButton— standalone close buttonLightbox.Provider— store-mode mount point
Labels
All strings rendered by the lightbox are defined in the labels prop. Pass the labels
that you want to change – the rest fall back to the default English values, which are
exported as DEFAULT_LABELS:
To change labels for all lightboxes in your application, set labels in
default props of the Lightbox component.
Accessibility
- Focus is trapped within the lightbox when opened and returned to the last active element when it is closed (
returnFocusprop) - Focus is moved to a hidden placeholder element instead of the first toolbar button when the lightbox is opened, so that no focus ring is displayed for pointer users (
withInitialFocusPlaceholderprop) - The content element has
role="dialog"witharia-modal="true"and an accessible name fromlabels.lightboxLabel– passaria-labelto override it for a single lightbox - Always set the
altproperty on image slides – without it the image is treated as decorative by screen readers; for video slides set thelabelproperty - All interactive elements have
aria-labelattributes; thelabelproperty is required for custom toolbar items aria-live="polite"region announces slide changes (including the current slidealt/label) to screen readers- Inactive slides are
inert– their content is hidden from screen readers and removed from the tab order, so only the current slide is reachable - Body scroll is locked when the lightbox is open
- Fullscreen mode entered from the toolbar is exited automatically when the lightbox is closed
Keyboard shortcuts
Escape always closes the lightbox. Other shortcuts are active when withKeyboardEvents is set
(default). They are ignored when focus is inside an input, textarea or media element anywhere in the
lightbox, and when focus is on a button, link or other widget inside slide content – so controls in
custom slides keep their own keyboard handling. F/T/Z only work when the corresponding feature is enabled: