Masonry Grid
A CSS column-count based masonry layout for variable-height content. Responsive breakpoints adjust column count for different screen sizes.
Live Demo (3 Columns)
Short card
Tall card
Medium card
Compact card
Feature card
Info card
Detail card
Stat card
Hero card
Basic Implementation
.masonry {
column-count: 3;
column-gap: 16px;
}
.masonry-item {
break-inside: avoid;
margin-bottom: 16px;
border-radius: 12px;
}
Responsive Breakpoints
Use media queries to reduce column count on smaller screens.
2 Columns (Tablet)
Short card
Tall card
Medium card
Compact card
Feature card
Info card
1 Column (Mobile)
Short card
Tall card
Medium card
.masonry {
column-count: 3;
column-gap: 16px;
}
/* Tablet: 768px - 1024px */
@media (max-width: 1024px) {
.masonry {
column-count: 2;
}
}
/* Mobile: below 768px */
@media (max-width: 768px) {
.masonry {
column-count: 1;
}
}
Breakpoint Reference
| Prop | Type | Default | Description | Required |
|---|
| desktop | >= 1024px | 3 | Three-column layout for wide screens | No |
| tablet | 768px - 1023px | 2 | Two-column layout for medium screens | No |
| mobile | < 768px | 1 | Single-column stack for small screens | No |
| column-gap | px | 16px | Horizontal space between columns | No |
| item-gap | px (margin-bottom) | 16px | Vertical space between items | No |
React Component
function MasonryGrid({
children,
columns = 3,
gap = 16,
}: {
children: React.ReactNode;
columns?: number;
gap?: number;
}) {
return (
<div style={{ columnCount: columns, columnGap: gap }}>
{children}
</div>
);
}
function MasonryItem({ children }: { children: React.ReactNode }) {
return (
<div style={{ breakInside: "avoid", marginBottom: 16 }}>
{children}
</div>
);
}
Guidelines
- Always set
break-inside: avoid on child items to prevent splitting across columns. - CSS columns fill top-to-bottom, then left-to-right. Keep this in mind for reading order.
- Use consistent item border-radius (min 8px) and spacing.
- For very long lists, consider virtualizing with a library.