Gallery
Rows, an even grid, or a masonry, for a list of cards that are not all the same height.
Gallery arranges a list of children. rows gives each child the full width, grid gives them
equal columns and stretches a short card to its row, and masonry lets each child keep its own
height. It does not draw the children. Interactive card
is the usual one: vertical and horizontal, short and long, in the same list.
Field notes
North shore survey
The tide line moved twelve meters.
Updated todayStudio
Paper samples
Three weights, one ink. The warm sheet is the one that holds a shadow, and the cool sheet is the one that disappears into the page.
3 weightsLibrary
Binding samples
Swatches for the three looks, pulled from the same sheet.
12 swatchesArchive
Marker index
48 marksSite
East bluff
A short visit. The path is still marked.
Yesterday
Switch the layout. The same six cards reflow. In the grid, the meta lines up across a row. In masonry, a short card sits higher than its neighbor. In rows, each card spans the list, and the horizontal one keeps its media beside the text.
Usage
import { Gallery } from '@/components/ui/gallery';
import {
InteractiveCard,
InteractiveCardContent,
InteractiveCardMedia,
InteractiveCardTitle,
} from '@/components/ui/interactive-card';
<Gallery layout="masonry" columns={3}>
<InteractiveCard asChild>
<a href="/notes/north-shore">
<InteractiveCardMedia>
<img src="/notes/north-shore.jpg" alt="" />
</InteractiveCardMedia>
<InteractiveCardContent>
<InteractiveCardTitle>North shore survey</InteractiveCardTitle>
</InteractiveCardContent>
</a>
</InteractiveCard>
</Gallery>Each child is one item. Pass the cards you already build. Gallery does not clone them or read their slots.
Rows, grid, and masonry
rows is one column. A horizontal card stays side by side, because the row is wide. A vertical
card's media spans that width.
grid is equal columns: one on a narrow screen, two from sm, and the columns count from lg
when that count is 3 or 4. A vertical card stretches to the height of its row, so a footer sits
on the same line as the footer beside it. A horizontal card keeps its picture as tall as its
text.
masonry uses the same column counts and lets each card be as tall as its content. The items
paint down the columns. A horizontal card in a narrow column wraps its text under the media,
because the card is narrower than 20rem.
columns is 2, 3, or 4, and 3 is the default. Rows ignore it.
Props
Gallery takes every <ul> attribute, plus these.
| Prop | Type | Default | What it does |
|---|---|---|---|
layout | "rows" | "grid" | "masonry" | "grid" | rows stacks full-width items. grid makes equal columns and stretches each item to its row. masonry packs items at their own height. |
columns | 2 | 3 | 4 | 3 | How many columns the grid or masonry uses from lg. Two columns arrive at sm. Rows stay one column. |
galleryVariants({ layout, columns }) returns the classes, for styling a list that is not a Gallery.
Accessibility
- Gallery is a
<ul>, and each child is an<li>, so a screen reader announces the count. The child keeps its own role. An interactive card rendered as a link is still a link, inside the list item. - Tab order follows the source. A grid and a row of cards match that order on screen. Masonry paints down the columns, so focus can move to a card that is not the next one you see.
- Gallery adds no keys of its own. A card keeps its inset focus ring, and a
revealcard's action still sits above the stretched title link. - The list does not clip its children, so a card can lift and draw its shadow without the row cutting them off.
- Gallery has no motion of its own. A card inside it still follows
motion-safe. - Forced colors keep each card's border. The list draws none of its own.
When to use something else
- One Interactive card, or a Card, when there is nothing to arrange.
- Item for a list of rows that are not framed cards.
ItemGroupstacks them and does not make columns. - Table when the cells line up in columns a reader compares.
Install
shadcn add @gesso/gallery