CSS Masonry layout — items packed into columns with no fixed row height — has been possible only with JavaScript libraries or multi-column CSS hacks until now. The grid-template-rows: masonry (Firefox behind a flag) and the newer masonry display value (Chrome experimental) finally bring true masonry to CSS. A polyfill path using grid-template-columns with subgrid is available for broader support today.
Problem: CSS Flexbox and Grid require JavaScript-calculated heights or multi-column hacks to achieve a true masonry layout — items that fill columns by height rather than rows.
Solution: Use the CSS grid-template-rows: masonry property (behind a flag in Firefox, shipping in other browsers) to enable native masonry in a grid container. Set grid-template-columns to define column widths and let the browser pack items into the shortest column automatically — no JavaScript required.
The examples below show the native masonry syntax, a @supports progressive enhancement pattern, and a CSS-only fallback using multi-column for browsers that do not yet support it.
/* ── Native masonry (Firefox flag / Chrome experimental) ── */
.masonry-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
grid-template-rows: masonry; /* the magic property */
gap: 1.25rem;
}
/* ── Progressive enhancement with @supports ── */
@supports (grid-template-rows: masonry) {
.masonry-grid {
grid-template-rows: masonry;
align-tracks: stretch; /* align items within their masonry track */
}
}
/* ── CSS-only fallback: multi-column layout ── */
@supports not (grid-template-rows: masonry) {
.masonry-grid {
display: block;
column-count: 3;
column-gap: 1.25rem;
}
.masonry-grid > * {
break-inside: avoid;
margin-block-end: 1.25rem;
}
}
/* ── Card item styles (work in both layouts) ── */
.masonry-grid > .card {
border-radius: 8px;
overflow: hidden;
box-shadow: 0 2px 8px rgb(0 0 0 / .1);
}
.masonry-grid > .card img {
width: 100%;
height: auto;
display: block;
}
/* ── Responsive columns ── */
@media (max-width: 600px) {
.masonry-grid {
grid-template-columns: 1fr;
column-count: 1;
}
}
NOTE: In Chrome you must enable the Experimental Web Platform features flag (chrome://flags/#enable-experimental-web-platform-features) to test grid-template-rows: masonry; for production use today the multi-column fallback or a lightweight JS library like Masonry.js is still needed in most projects.