A Pinterest-style column layout via native CSS multi-column (column-count + column-width),
not JS height measurement — items fill down one column before wrapping to the next, and the
browser itself drops columns as the container narrows.
The tradeoff for that simplicity: items are read down each column in turn, not left-to-right by row, which is the standard CSS-columns masonry behavior.
<MasonryGrid minColumnWidth={160}>
...
</MasonryGrid>Examples
A gallery of variable-height cards — this is the layout MasonryGrid earns its keep on, since a
regular Grid would leave uneven gaps under the shorter items in each row:
<MasonryGrid minColumnWidth={240} gap="16">
{photos.map((photo) => (
<Media key={photo.id} src={photo.src} alt={photo.alt} />
))}
</MasonryGrid>Because it reads down-then-across, keep DOM order in mind for content where reading order matters
— for a photo gallery it rarely does, but for anything a screen-reader user steps through
linearly, a regular Grid (which preserves left-to-right, top-to-bottom order) is the safer
default.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| columns | number | 3 | Upper bound on column count — the browser renders fewer (down to 1) once `minColumnWidth` no longer fits, which is what makes this responsive with no breakpoint props of its own. |
| gap | s | m | l | xl | xs | 0 | 1 | 2 | 4 | 8 | 12 | 16 | 20 | 24 | 32 | 40 | 48 | 56 | 64 | 80 | 96 | 128 | 160 | "16" | Space between columns AND between stacked items in a column — a plain CSS `gap` only gives the first half, since multi-column has no concept of vertical space between stacked items, so each item also gets this as its own `margin-bottom`. |
| minColumnWidth | number | 240 | The narrowest a column may get before the browser drops one, in px. |