Skip to content

CSS Grid Bento Photo Gallery

Bento-style photo gallery with mixed tile sizes from CSS Grid spans, hover captions and a keyboard-friendly dialog lightbox.

Live preview

Open in new tab

Code

A bento-style photo gallery built with CSS Grid, where tiles of different sizes lock together into one tidy block, plus a small vanilla JavaScript lightbox. It works well for travel blogs, portfolio pages, hotel and venue sites or any "highlights" section that needs more character than a uniform grid.

How it works

The root section.bpg-gallery contains a .bpg-head and the .bpg-grid. Each photo is a figure.bpg-tile with a link (a.bpg-link) that wraps the thumbnail img.bpg-img, and a figcaption.bpg-cap with a .bpg-title and .bpg-place. The grid uses fixed row heights from --bpg-row and grid-auto-flow: dense. Three modifiers decide the shape: .bpg-tile--big spans two columns and two rows, .bpg-tile--tall spans two rows and .bpg-tile--wide spans two columns. On phones the grid has two columns; from 720px it switches to four, and the dense packing fills every gap. Images use object-fit: cover, so any photo ratio fits its tile.

Captions slide up on hover or keyboard focus, are always visible on the featured tile, and are always shown on touch screens via (hover: none). Each link points to a large version of the photo, so without JavaScript a click simply opens the image. With JavaScript, the script listens for click on every .bpg-link, prevents navigation and opens the dialog.bpg-dialog with showModal(). It shows the large image in .bpg-full, the caption in .bpg-full-cap and a counter such as "3 / 7". .bpg-prev and .bpg-next loop through the photos.

The photos are from Unsplash and are meant as placeholders; replace them with your own images and update the alt text.

Customization

  • --bpg-row on .bpg-gallery: row height (9rem on phones, 11.25rem from 720px); taller rows make every tile taller.
  • --bpg-gap and --bpg-radius: spacing between tiles and their corner rounding.
  • Move .bpg-tile--big, .bpg-tile--tall or .bpg-tile--wide to other figures to create a new mosaic; tiles without a modifier fill one cell.
  • grid-template-columns in .bpg-grid inside the 720px media query: use repeat(6, ...) for a wider, denser mosaic.
  • --bpg-bg, --bpg-ink and --bpg-accent: section background, text color and the eyebrow / focus color.
  • The href of each .bpg-link sets the image the lightbox loads; point it to a larger file than the thumbnail.

Accessibility

Every thumbnail has a descriptive alt, width, height, decoding="async", and every image after the first two uses loading="lazy". Links show a visible focus ring, and focusing a tile reveals its caption. The lightbox is a native modal dialog with an aria-label: focus moves to the close button, Escape closes it, the Left and Right arrow keys switch photos, a click on the backdrop closes it, and focus returns to the tile that opened it. The caption inside the viewer is an aria-live region, so screen readers announce the new photo. Zoom and caption transitions are turned off with prefers-reduced-motion.

Usage notes

Several galleries can share a page because the script scopes everything to each .bpg-gallery.

Requirements

No dependencies. Pure HTML, CSS and JavaScript.

CSS Grid Bento Photo Gallery – Pure CSS galleries component screenshot
CSS Grid Bento Photo Gallery · Pure CSS Galleries

More Galleries

Masonry Image Gallery – Pure CSS galleries preview

Masonry Image Gallery

Pure CSS masonry image gallery using multi-column layout, with hover and focus captions that slide up over each photo. No JavaScript needed.

Polaroid Photo Gallery – Pure CSS galleries preview

Polaroid Photo Gallery

Pure CSS polaroid gallery on a cork board: tilted photo frames with tape and handwritten captions that straighten and lift on hover or focus.

Filterable Portfolio Gallery – Bootstrap 5 galleries preview

Filterable Portfolio Gallery

Dark Bootstrap 5 portfolio gallery with pill filter buttons, automatic category counts, fade-in tiles and a screen reader status message.

Gallery with Lightbox – Tailwind CSS galleries preview

Gallery with Lightbox

Tailwind CSS mosaic image gallery that opens an accessible lightbox with captions, arrow-key and swipe navigation, focus trap and preloading.