Gallery & Lightbox
A photo gallery is really two problems, and they are best solved by two
libraries.
react-photo-album handles layout — fitting uneven aspect ratios
into rows or columns without cropping anything — and
yet-another-react-lightbox handles the viewer: keyboard navigation, pinch
zoom, captions, thumbnails, fullscreen and slideshow.Neither owns the page chrome, so the whole gallery drops inside a
Card
unchanged.Rows layout
Justified rows with captions
Click any photo to open it. Arrow keys move, Escape closes, the counter and thumbnail strip come from plugins — and the card around it all is Algorize UI.
- Give every photo a
width - and
height. The album computes its layout from the aspect ratio before the images load — omit them and the rows reflow as each one arrives. srcSet- is what keeps a grid of 1600px originals from being downloaded at full size. The album picks the right entry for the rendered width.
targetRowHeight- is a target, not a rule — the last row and narrow viewports both bend it to avoid cropping.
slides- on the lightbox accepts the same array, so
titleanddescriptionon a photo become the caption with no second data shape.
Installation
This example also uses these Algorize UI components — install whichever
your project does not already have:
Masonry layout
The same two libraries in a different arrangement:
MasonryPhotoAlbum packs
uneven heights into columns, and the lightbox is opened from a hover affordance
rather than the whole tile — so the overlay button is yours while the album's own
image element stays untouched.Masonry columns with a hover control
Column count responds to the container, not the viewport. Fullscreen, slideshow, zoom and download are four plugin imports.
- Pass
columns - a function of the container width. Reading the container rather than the viewport is what keeps the album correct inside a sidebar or a modal.
render.extras- layers your own markup over a tile without replacing the image element — the hover overlay here.
componentsProps.button- puts
group relativeon the tile's own button, which is what letsgroup-hoverdrive that overlay. plugins- are additive and each ships its own CSS where it needs it —
captions.css,counter.css,thumbnails.css. Zoom and fullscreen need none.
Installation
Same two packages as above —
MasonryPhotoAlbum and the extra plugins ship
inside them, so there is nothing new to add:The layouts and the plugins
react-photo-album exports three album components, all taking the same photo
array:| Component | Arrangement | Good for |
|---|---|---|
RowsPhotoAlbum | Justified rows of equal height | Mixed landscape and portrait, editorial feel |
ColumnsPhotoAlbum | Fixed columns, photos in order | Reading order matters |
MasonryPhotoAlbum | Columns balanced by height | Tall and wide mixed, no gaps |
The lightbox is plugin-based, and each plugin is opt-in:
| Plugin | Adds | Extra CSS |
|---|---|---|
Captions | Title and description overlay | captions.css |
Counter | "3 / 12" position | counter.css |
Thumbnails | Filmstrip | thumbnails.css |
Zoom | Pinch and wheel zoom | — |
Fullscreen | Fullscreen API | — |
Slideshow | Timed auto-advance | — |
Download | Save the original | — |
Video | Video slides alongside photos | — |
Notes
Theming the viewer. The lightbox reads its own CSS variables, adapting
automatically to light and dark modes with a translucent, blurred frosted-glass
backdrop (
backdrop-filter: blur(16px)).Server rendering. The lightbox renders nothing until
open is true, so it is
safe anywhere. The album has a dedicated react-photo-album/ssr entry point for
server-rendered layout if the first paint matters to you.Next.js images. Both examples use a plain
<img> so the code runs unchanged
in any React app. To route through next/image, pass a custom image renderer via
the album's render.image — the layout maths is unaffected.