Skip to main content

MediaGrid

MediaGrid

Responsive gallery of media thumbnails with keyboard navigation

Tags: component media data-display

View Demo

MediaGrid lays out a list of media items as thumbnails and opens the Lightbox when one is chosen. It handles mixed media: video and audio tiles gain a play affordance and a duration badge, and items with no thumbnail fall back to a typed icon.

Import​

<script>
  import { MediaGrid } from '@classic-homes/theme-svelte';
</script>

Basic Usage​

<script>
  const photos = [
    { id: '1', kind: 'image', src: '/one.jpg', alt: 'Front elevation' },
    { id: '2', kind: 'image', src: '/two.jpg', alt: 'Kitchen' },
    { id: '3', kind: 'video', src: '/tour.mp4', poster: '/tour.jpg', title: 'Walkthrough' },
  ];
</script>

<MediaGrid items={photos} label="Project photos" />

Props​

Prop Type Default Description
items MediaItem[] required Items to display
label string 'Media gallery' Accessible name for the gallery list
variant 'grid' | 'masonry' 'grid' Uniform tiles, or natural heights via CSS columns
columns MediaGridColumns { base: 2, md: 3, lg: 4 } Column counts per breakpoint
gap 'none' | 'sm' | 'md' | 'lg' 'md' Gap between tiles
ratio 'square' | 'video' | 'photo' | 'portrait' | 'wide' | number 'square' Aspect ratio of each tile; ignored in masonry
lightbox boolean true Open the built-in lightbox on selection
singleTabStop boolean true Keep the gallery to one tab stop and move with the arrow keys
onSelect (index: number, item: MediaItem) => void - Called with the selected index and item
class string - Additional CSS classes

Responsive Columns​

columns takes a count per breakpoint. Omitted breakpoints inherit the one below:

<MediaGrid items={photos} columns={{ base: 2, sm: 3, md: 4, lg: 5, xl: 6 }} />

Counts from 1 to 6 are supported at every breakpoint.

Masonry​

masonry preserves each image's own height. Note that CSS columns fill top-to-bottom, so the visual order runs down each column rather than across each row — reach for it when the items have no meaningful sequence.

<MediaGrid items={photos} variant="masonry" columns={{ base: 2, md: 3 }} />

Custom Selection Handling​

Turn the built-in lightbox off to route selection somewhere else:

<MediaGrid items={photos} lightbox={false} onSelect={(index, item) => goto(`/photos/${item.id}`)} />

Accessibility​

  • Renders a labelled list, so screen readers announce the gallery and its item count.
  • Each tile is a real button named from the item's title or alt text.
  • By default the gallery is a single tab stop; arrow keys move between tiles. ↓ and ↑ move a full row, with the column count read from the live layout rather than the columns prop.
  • Home and End jump to the first and last tile.
  • Set singleTabStop={false} for small galleries where a tab stop per tile is preferable.
  • Lightbox - The full-screen viewer MediaGrid opens
  • MediaCarousel - One item at a time instead of a grid
  • Image - Renders each tile's thumbnail
  • AspectRatio - Holds each tile at a fixed ratio
On this page