CSS Masonry Layout Draft: Native Pinterest Layouts in the Browser
AI generated
CSS · Masonry · Grid · Browser Flags · Polyfill
CSS Masonry Layout Draft
Native Pinterest layouts without JavaScript

Masonry layouts, grids in which items of varying height are stacked without gaps, have been a JavaScript problem for years. The CSS Masonry draft specification brings this behavior natively into the browser: grid-template-rows: masonry promises what previously only libraries such as Masonry.js or Isotope could deliver.

11 min read grid-template-rows: masonry · browser flags · polyfill comparison · Interop 2025 CSS Grid Level 3 · Experimental · Firefox / Chrome Nightly

1. What is a masonry layout?

A CSS Masonry Layout describes a grid layout in which items are arranged in columns, but the row height is not fixed. Instead, every new item slots into the column with the least amount of used vertical space, much like stones in a wall (hence the name masonry). The result is a dense grid without gaps between elements of different heights, the effect that made Pinterest famous.

The fundamental problem with classic CSS Grid is that grid layouts rely on a strict row and column raster. When items have different heights, you either end up with gaps between them (because the row is as tall as the tallest item) or items need a grid-row-span, which requires knowing their exact height in advance. Neither is workable for dynamic content. Previous solutions relied on JavaScript (Masonry.js, Isotope, react-masonry-css), multi-column layouts (column-count), or absolute positioning, all with significant drawbacks in performance, accessibility, or document order.

The CSS Masonry Draft solves the problem at the level of the layout algorithm itself: the browser calculates the placement of every item using a masonry algorithm, without JavaScript having to measure element heights and compute positions. That is not only simpler to implement, it is also more performant and more accessible, because document order is preserved.

2. The CSS Masonry draft specification

The CSS Masonry feature is part of the CSS Grid Layout Level 3 specification, developed by the CSS Working Group. Its current status is "Editor's Draft," meaning the specification is not yet stable, but the basic API is defined and browser implementations already exist. The specification defines masonry as an extension of the existing grid model: a grid container can use the masonry algorithm instead of the normal grid algorithm on one of its axes.

There was an important debate within the CSS Working Group: Google proposed defining CSS Masonry as a separate property outside of grid (display: masonry), while Mozilla favored integrating it into grid (grid-template-rows: masonry). After a lengthy discussion, the Working Group settled on the grid integration approach, which also matches Mozilla's implementation. That means CSS Masonry can use the entire grid toolbox: gap, alignment, spanning, and named lines.

3. grid-template-rows: masonry: syntax and behavior

The basic syntax for CSS Masonry is simple: grid-template-rows: masonry combined with a normal grid-template-columns definition. The masonry keyword on the row axis activates the masonry algorithm for that direction. Alternatively, grid-template-columns: masonry can be used to create a horizontal masonry (columns grow to the right, items fill in row direction), which is less common but useful for special layouts.

The behavior of the CSS Masonry algorithm works as follows: the container defines the columns normally (for example grid-template-columns: repeat(3, 1fr)). Items are placed in reading order but are not forced into fixed rows; they always fill the shortest available column. gap works normally and creates spacing between all items both horizontally and vertically. Items can be given grid-column: span 2 to stretch across multiple columns.

/* CSS Masonry Draft: basic syntax */

/* Enable masonry on the row axis */
.masonry-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: masonry; /* activates masonry algorithm */
  gap: 1rem;
}

/* Responsive masonry: auto-fill columns with min width */
.masonry-responsive {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  grid-template-rows: masonry;
  gap: 1.25rem;
}

/* Horizontal masonry (items fill row-by-row) */
.masonry-horizontal {
  display: grid;
  grid-template-rows: repeat(3, auto);
  grid-template-columns: masonry;
  gap: 1rem;
}

/* Feature detection: apply masonry only where supported */
@supports (grid-template-rows: masonry) {
  .gallery {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
    grid-template-rows: masonry;
    gap: 1rem;
  }
}

4. A first example: an image gallery as a masonry grid

The classic practical CSS Masonry example is an image gallery with photos of different aspect ratios. With a normal grid, all images would be scaled to the same height, losing their original aspect ratio or leaving gaps. With CSS Masonry, every image keeps its natural aspect ratio, and the algorithm stacks the images into the shortest column without gaps.

An important detail for image galleries: img { width: 100%; height: auto; display: block; } is required so that images keep their natural height and the CSS Masonry algorithm can work correctly. Images with a fixed height would undermine the masonry algorithm, since all images would then have the same height. The block display also prevents the default gap that appears beneath inline images.

For cards with variable text content, such as blog posts with teasers of different lengths or product cards with variable description text, CSS Masonry is even more useful. Instead of stretching every card to the height of the tallest one, or writing JavaScript to keep the spacing even, the browser arranges the cards automatically without gaps. That is the core promise of the specification draft.

5. Alignment and spanning in masonry grids

Since CSS Masonry is defined as a grid extension, the familiar alignment properties still apply. justify-items and align-items work for items inside a masonry container. justify-self can be used on individual items to position them within their column. This is particularly useful for items that are narrower than their column, such as buttons or small images in a CSS Masonry layout.

Spanning in CSS Masonry is limited to the column axis. grid-column: span 2 lets an item span two columns, which works just like in a normal grid. grid-row: span 2 makes no sense in a masonry layout, since the row axis is controlled by the masonry algorithm and has no fixed rows. That is an important difference from regular grid spanning.

/* CSS Masonry Draft: alignment and spanning */

.masonry-gallery {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: masonry;
  gap: 1rem;
  align-tracks: start; /* align items to the top of each track */
}

/* Featured item spans two columns */
.masonry-gallery .featured {
  grid-column: span 2;
}

/* Small item: centered within its column */
.masonry-gallery .small-badge {
  justify-self: center;
  width: 80%;
}

/* Images: natural aspect ratio preserved */
.masonry-gallery img {
  width: 100%;
  height: auto;
  display: block;
  border-radius: 0.5rem;
  object-fit: cover;
}

/* Masonry with named grid lines for semantic spanning */
.masonry-layout {
  display: grid;
  grid-template-columns: [main-start] 1fr 1fr [sidebar-start] 1fr [sidebar-end main-end];
  grid-template-rows: masonry;
  gap: 1.5rem;
}

6. Browser flags: how to enable the preview

The CSS Masonry Draft is available in Firefox and in Chromium-based browsers behind experimental flags. In Firefox, grid-template-rows: masonry can be enabled since Firefox 77 via layout.css.grid-template-masonry-value.enabled in about:config. In Chrome Canary and Chromium Nightly builds, the feature is available via the #enable-experimental-web-platform-features flag in chrome://flags. Production Chrome and Safari still do not support CSS Masonry without a flag as of May 2026.

For development, Firefox Nightly is recommended as the reference browser for CSS Masonry features. The Firefox implementation follows the current specification most closely, since Mozilla played a major role in developing the CSS Masonry proposal. Chrome Canary is useful for cross-browser testing, but the implementations can differ in details while the specification is still unfinished.

For production environments, @supports (grid-template-rows: masonry) is the right strategy: where supported, the native CSS Masonry layout is used, and elsewhere a multi-column or flexible grid fallback applies instead. This progressive enhancement approach lets you experiment with the native API today without confronting unsupported users with broken layouts.

7. Polyfill comparison: JavaScript vs. native CSS

Before the CSS Masonry Draft, JavaScript libraries were the only viable option for true masonry layouts. The best known is Desandro's Masonry.js, one of the most widely used layout libraries since 2010. It measures the height of every element, calculates positions, sets absolute positions, and reacts to resize events. The result is correct, but expensive: the initial layout requires DOM reads for every item (layout thrashing), resize events must be debounced, and JavaScript has to load and execute before the layout is correct.

An alternative CSS-only approach without JavaScript is column-count or columns: elements are arranged in columns, but in column order rather than reading order. An item in column 1 appears before an item in column 2, regardless of which one comes first in the HTML. That is problematic for content with a semantic order, such as blog posts sorted by date, since screen readers and tab navigation follow DOM order, not the visual column arrangement. Native CSS Masonry solves this problem because it preserves document order.

8. CSS Masonry approaches compared

The different masonry implementation approaches differ fundamentally in performance, accessibility, and implementation effort.

Approach DOM order Performance Browser support
CSS Masonry Draft Preserved Native, no JS Behind flags only
Masonry.js Preserved JS overhead, layout thrashing All browsers
column-count CSS Column order Native, no JS All browsers
Grid + grid-row: span Preserved Native All browsers
Flexbox multi-column Column order (manual) Native All browsers

The "Grid + grid-row: span" variant, the best known CSS-only alternative without CSS Masonry, only works for content with known heights. You divide the content height by a fixed row height (for example 10px) and set grid-row: span X accordingly. That is high maintenance, requires either JavaScript for the calculation or fixed heights, and fails for dynamic content. It is the best possible CSS approximation without native CSS Masonry, but not a full replacement.

/* CSS Masonry alternatives: current best practices */

/* Option 1: column-count (DOM order caveat!) */
.gallery-columns {
  columns: 3 240px; /* 3 columns, min 240px each */
  column-gap: 1rem;
}
.gallery-columns > * {
  break-inside: avoid; /* prevent items from splitting */
  margin-bottom: 1rem;
}

/* Option 2: CSS Grid with JS-calculated span (dynamic) */
.masonry-grid-approx {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  grid-auto-rows: 10px; /* small row unit for JS span calculation */
  gap: 1rem 1rem;
}
/* JS sets: element.style.gridRowEnd = 'span ' + Math.ceil(height / 10) */

/* Option 3: Progressive enhancement with @supports */
.gallery { columns: 3; column-gap: 1rem; }
.gallery > * { break-inside: avoid; margin-bottom: 1rem; }

@supports (grid-template-rows: masonry) {
  .gallery {
    columns: unset;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    grid-template-rows: masonry;
    gap: 1rem;
  }
  .gallery > * { margin-bottom: 0; }
}

9. Interop 2025 and the road to standardization

The Interop project is a collaboration between browser vendors Apple, Google, Microsoft, and Mozilla to improve cross-browser compatibility for important web features. CSS Masonry was a candidate for Interop 2025 and was assigned high priority, which signals that browser vendors consider the feature important. Interop features receive coordinated implementation work across all participating browsers, historically the fastest path from a draft to baseline status.

For developers, this means CSS Masonry is not a speculative feature but one with a clear standardization path. The question is not whether but when it will be available without flags in every browser. A conservative estimate based on similar features is 12 to 24 months after Interop adoption. That means teams should start experimenting with the native API today, build fallback strategies, and prepare for the progressive enhancement transition.

Mironsoft

Modern CSS layouts, masonry galleries, and Hyva theme development

Masonry layouts today, without the JavaScript overhead?

We implement masonry galleries with progressive enhancement: native CSS Masonry for supporting browsers, elegant column-count fallbacks for everyone else, while preparing projects for full browser support.

Gallery layouts

Masonry galleries for Magento product pages and blog listings, with CSS and a JS fallback

Progressive enhancement

An @supports-based strategy for native masonry with a robust fallback

Hyva integration

Masonry layouts in Tailwind v4 and Alpine.js components for Hyva themes

10. Summary

The CSS Masonry Draft brings native masonry layout through grid-template-rows: masonry as part of the CSS Grid Level 3 specification. The algorithm places items into the shortest available column, preserves DOM order, and makes JavaScript libraries such as Masonry.js unnecessary. Gap, alignment, and column spanning from the regular grid model all work fully.

As of May 2026, CSS Masonry is available in Firefox Nightly and Chrome Canary behind flags. @supports (grid-template-rows: masonry) enables progressive enhancement: the native API for supporting browsers, a column-count fallback for everyone else. With Interop 2025, the standardization path is clear. Projects that need masonry today should prepare the native API and build with robust fallbacks.

CSS Masonry Draft: the essentials at a glance

Syntax

display: grid; grid-template-columns: repeat(3, 1fr); grid-template-rows: masonry; gap: 1rem;

Browser support (May 2026)

Firefox Nightly (layout.css.grid-template-masonry-value.enabled) and Chrome Canary (#enable-experimental-web-platform-features). No production support without a flag.

Advantages vs. JS polyfills

No layout thrashing, DOM order preserved, no JavaScript overhead, native grid features (gap, alignment, spanning) available.

Fallback today

@supports strategy: columns: 3 as a fallback, @supports (grid-template-rows: masonry) for native masonry. Progressive enhancement without compromises.

11. FAQ: CSS Masonry Layout

1What is CSS Masonry Layout?
A grid extension: items always fill the shortest column. Dense grids with items of varying height and no gaps, natively, without JavaScript.
2How do you enable it in Firefox?
about:config, then layout.css.grid-template-masonry-value.enabled, then true. Chrome Canary: chrome://flags, then #enable-experimental-web-platform-features.
3Production ready?
No (as of May 2026). Behind flags only. An @supports fallback is recommended: column-count for everyone, native masonry where supported.
4Better than column-count?
Yes, DOM order is preserved. column-count separates visual order from DOM order, which breaks screen readers and tab navigation.
5Does gap work in CSS Masonry?
Yes. gap, column-gap, and row-gap work as in regular grid, between all items horizontally and vertically.
6Is column spanning possible?
Yes. grid-column: span 2 works. grid-row: span has no effect, since the row axis is controlled by the masonry algorithm.
7CSS Masonry vs. Masonry.js?
Masonry.js measures DOM elements with JS and sets absolute positions, causing layout thrashing. Native: part of the browser rendering, no JS overhead.
8What is Interop 2025?
Coordinated browser implementation of important web features by Apple, Google, Microsoft, and Mozilla. CSS Masonry as a candidate means prioritized standardization.
9Safe fallback?
.gallery { columns: 3; } @supports (grid-template-rows: masonry) { .gallery { columns: unset; display: grid; grid-template-rows: masonry; } }
10Debate: grid vs. display: masonry?
Google wanted display: masonry, Mozilla wanted grid integration. The Working Group chose grid integration, enabling access to gap, alignment, and spanning.