Masonry Layouts: Three Paths, One Open Question
Pinterest-style masonry layouts have long been a JavaScript affair. Developers who want that organic, gap-filling flow of items — where shorter pieces let the next row rise up to fill the space — have had to reach for libraries or hack around CSS Grid’s rigid structure. But native CSS support may finally be on the horizon. The question is no longer whether masonry should be built into CSS, but how.
Three proposals are now on the table. The first extends CSS Grid with a masonry value. The second carves out a standalone masonry module. The third, unveiled by Apple’s WebKit team in March 2025, attempts to unify Flexbox, Grid, and masonry into a single system. Each approach has its champions and its trade-offs.
The Current State: Hacks And Workarounds
Without native support, developers have resorted to creative — but fragile — workarounds. One common approach uses CSS Grid with a grid-auto-rows trick, paired with JavaScript to measure item heights after render, calculate spans, and dynamically set grid-row-end. Event listeners then recalculate everything on page load and window resize.
/* HTML */
<div class="masonry-grid">
<div class="masonry-item"><img src="image1.jpg" alt="Image 1"></div>
<div class="masonry-item"><p>Short text content here.</p></div>
<div class="masonry-item"><img src="image2.jpg" alt="Image 2"></div>
<div class="masonry-item"><p>Longer text content that spans multiple lines to show height variation.</p></div>
</div>
/* CSS */
.masonry-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); /* Responsive columns */
grid-auto-rows: 10px; /* Small row height for precise spanning */
grid-auto-flow: column; /* Fills columns left-to-right */
gap: 10px; /* Spacing between items */
}
.masonry-item {
/* Ensure content doesn’t overflow */
overflow: hidden;
}
.masonry-item img {
width: 100%;
height: auto;
display: block;
}
.masonry-item p {
margin: 0;
padding: 10px;
}
// JavaScript
function applyMasonry() {
const grid = document.querySelector('.masonry-grid');
const items = grid.querySelectorAll('.masonry-item');
items.forEach(item => {
// Reset any previous spans
item.style.gridRowEnd = 'auto';
// Calculate the number of rows to span based on item height
const rowHeight = 10;
const gap = 10;
const itemHeight = item.getBoundingClientRect().height;
const rowSpan = Math.ceil((itemHeight + gap) / (rowHeight + gap));
// Apply the span
item.style.gridRowEnd = `span ${rowSpan}`;
});
}
// Run on load and resize
window.addEventListener('load', applyMasonry);
window.addEventListener('resize', applyMasonry);
This gets close to a masonry look, but it falls short in several ways. The JavaScript dependency defeats the "pure CSS" dream, recalculating spans on resize or content changes can cause lag on complex pages, and the visual flow can diverge from the logical DOM order. Lazy-loaded images or shifting content can trigger layout jumps as spans need recalculation. It’s a mental juggling act that forces you to switch between CSS and JavaScript just to tweak a layout.
Option One: Masonry Inside CSS Grid
The first proposal keeps masonry within the Grid ecosystem. A draft of CSS Grid Level 3 introduces grid-template-rows: masonry, an experimental value currently available in Firefox Nightly. In this model, columns stay as a grid axis while rows adopt masonry behaviour. Child elements flow vertically, respecting column tracks but not row constraints.
.masonry-grid {
display: grid;
gap: 10px;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
grid-template-rows: masonry;
}
The appeal here is familiarity. Developers who already know grid-template-columns or grid-area have a head start with masonry — it just extends existing capabilities. Chrome DevTools’ grid overlay and Firefox’s layout inspector already provide robust tooling.
But there are downsides. Grid’s spec is already dense with properties like align-content and grid-auto-flow; adding masonry on top risks creating a labyrinth. Edge cases remain foggy — what happens when an item should span several columns masonry-style? What about misaligned gaps across columns? Early tests hint at items jumping unpredictably with dynamically loaded content. And browser support is minimal: Firefox Nightly only, with polyfills unable to bridge the gap.
Option Two: A Dedicated Masonry Module
The alternative proposal imagines a display: masonry value — a clean slate that doesn’t lean on Grid’s rigid tracks or Flexbox’s linear flow. Such a module would prioritise fluidity over structure, with items cascading down columns and filling gaps naturally by default.
In this vision, direction and spacing would be controlled via simple properties, with room for extras that mimic Grid conveniences:
.masonry {
display: masonry;
masonry-direction: column;
gap: 1rem;
}
Hypothetical additions like masonry-columns: auto could replicate Grid’s repeat(auto-fill, minmax()), and masonry-align: balance might even out column lengths. The central idea is separation of concerns: Grid for order, Masonry for flow. No more wrestling with Grid properties that don’t quite fit the job.
The main hurdle is starting from zero. A brand-new spec means browser vendors must rally behind it, and that takes time. There’s also the potential for confusion — developers might wonder whether to reach for Grid or Masonry in a given situation. The waters would muddy before they clear.
Option Three: Item Flow’s Unified Approach
Apple’s WebKit team stepped into the debate in March 2025 with a third option: Item Flow. Instead of choosing between extending Grid or starting fresh, this proposal unifies concepts from Flexbox, Grid, and masonry into a single property set. It replaces flex-flow and grid-auto-flow with a item-flow shorthand and four longhand properties:
item-direction— controls flow direction (e.g.,row,column,row-reverse).item-wrap— manages wrapping (e.g.,wrap,nowrap,wrap-reverse).item-pack— determines packing density (e.g.,sparse,dense,balance).item-slack— adjusts tolerance so items can shrink or shift to fit.
Under this system, masonry becomes a natural outcome of these properties rather than a distinct feature. A masonry layout could be achieved like this:
.container {
display: grid; /* or flex */
item-flow: column wrap dense;
/* long hand version */
item-direction: column;
item-wrap: wrap;
item-pack: dense;
gap: 1rem;
}
This configuration lets items flow vertically, wrap into columns, and pack tightly — mirroring masonry’s organic look. The dense packing option draws from Grid’s auto-flow: dense to reorder items and minimise gaps, while item-slack could fine-tune spacing.
Item Flow’s promise is its wide applicability. It also extends Grid and Flexbox in ways developers have long requested, such as nowrap for Grid or balance packing for Flexbox. But the proposal is still under discussion, with open questions about property naming and clarity. As of April 2025, no browser has implemented Item Flow, and the CSS Working Group continues to gather feedback.
Weighing The Options
There is no single right answer to where masonry belongs in CSS. The core tension sits between keeping the platform simple, making layouts perform well, and giving developers flexible tools. Pushing masonry into Grid risks overloading a system that already handles a great deal of complexity. A separate display: masonry module would be cleaner conceptually but introduces yet another layout model to learn. Item Flow tries to sidestep that trade-off by proposing one mechanism that could serve both Grid and Flexbox, potentially settling the argument before it hardens into incompatible implementations.
The competing proposals each carry their own baggage:
- Grid with masonry: Reuses familiar syntax but feels bolted on, with unresolved accessibility and specification issues.
- Standalone module: Purpose-built and tidy, but a new syntax for authors to absorb.
- Item Flow: Promises to unify existing layout models and add masonry as a byproduct, yet it is not implemented and its naming and details are still under debate.
Item Flow’s appeal is that it does not force a choice between supporting current layouts and adding masonry. But a proposal only becomes a feature with browser buy-in and sustained community pressure.
Where The Debate Lands
The practical question is not which idea is prettiest, but which path actually ships. CSS Grid has already given developers a preview of masonry behavior, which makes the standalone module seem redundant to some. Item Flow, on the other hand, could render both approaches obsolete by folding masonry into a broader layout concept that also handles flex and grid cases. WebKit’s shorthand proposal for merging these concepts is the most concrete step in that direction so far.
What happens next depends less on technical merit and more on implementation momentum. Browser vendors need to align, the spec needs to survive review cycles, and the community has to show it wants something beyond JavaScript-based solutions. Until then, the sensible move is to test the current Grid-based approach, watch Item Flow’s progress, and add feedback where it counts.
Further Reading
- “Native CSS Masonry Layout in CSS Grid” by Rachel Andrew
- “Should Masonry be part of CSS Grid?” by Ahmad Shadeed
- “CSS Masonry & CSS Grid” by Geoff Graham
- “Masonry? In CSS?!” by Michelle Barker
- “Native CSS Masonry Layout in CSS Grids” by Chris Coyier
- “Item Flow Part 1: A Unified Concept for Layout” by WebKit




