You’ve got a Pinterest-style layout to build, but you’re tired of JavaScript. Could CSS finally have the answer? Well, for a beginner, taking a look at the pins on your Pinterest page, you might be convinced that the CSS grid layout is enough, but not until you begin to build do you realise display: grid
with additional tweaks is less than enough. In fact, Pinterest built its layout with JavaScript, but how cool would it be if it were just CSS? If there were a CSS display property that gave such a layout without any additional JavaScript, how awesome would that be?
Maybe there is. The CSS grid layout has an experimental masonry value for grid-template-rows
. The masonry layout is an irregular, flowing grid. Irregular in the sense that, instead of following a rigid grid pattern with spaces left after shorter pieces, the items in the next row of a masonry layout rise to fill the spaces on the masonry axis. It’s the dream for portfolios, image galleries, and social feeds — designs that thrive on organic flow. But here’s the catch: while this experimental feature exists (think Firefox Nightly with a flag enabled), it’s not the seamless solution you might expect, thanks to limited browser support and some rough edges in its current form.
Maybe there isn’t. CSS lacks native masonry support, forcing developers to use hacks or JavaScript libraries like Masonry.js. Developers with a good design background have expressed their criticism about the CSS grid form of masonry, with Rachel highlighting that masonry’s organic flow contrasts with Grid’s strict two-dimensional structure, potentially confusing developers expecting Grid-like behaviour or Ahmad Shadeed fussing about how it makes the grid layout more complex than it should be, potentially overwhelming developers who value Grid’s clarity for structured layouts. Geoff also echoes Rachel Andrew’s concern that “teaching and learning grid to get to understand masonry behaviour unnecessarily lumps two different formatting contexts into one,” complicating education for designers and developers who rely on clear mental models.
Perhaps there might be hope. The Apple WebKit team just sprung up a new contender, which claims not only to merge the pros of grid and masonry into a unified system shorthand but also includes flexbox concepts. Imagine the best of three CSS layout systems in one.
Given these complaints and criticisms — and a new guy in the game — the question is:
Should CSS Grid expand to handle Masonry, or should a new, dedicated module take over, or should
item-flow
just take the reins?
The State Of Masonry In CSS Today
Several developers have attempted to create workarounds to achieve a masonry layout in their web applications using CSS Grid with manual row-span hacks, CSS Columns, and JavaScript libraries. Without native masonry, developers often turn to Grid hacks like this: a grid-auto-rows
trick paired with JavaScript to fake the flow. It works — sort of — but the cracks show fast.
For instance, the example below relies on JavaScript to measure each item’s height after rendering, calculate the number of 10px rows (plus gaps) the item should span while setting grid-row-end
dynamically, and use event listeners to adjust the layout upon page load and window resize.
/* HTML */
Longer text content that spans multiple lines to show height variation.
/* 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 Grid hack gets us close to a masonry layout — items stack, gaps fill, and it looks decent enough. But let’s be real: it’s not there yet. The code sample above, unlike native grid-template-rows: masonry
(which is experimental and only exists on Firefox Nightly), relies on JavaScript to calculate spans, defeating the “no JavaScript” dream. The JavaScript logic works by recalculating spans on resize or content change. As Chris Coyier noted in his critique of similar hacks, this can lead to lag on complex pages.
Also, the logical DOM order might not match the visual flow, a concern Rachel Andrew raised about masonry layouts generally. Finally, if images load slowly or content shifts (e.g., lazy-loaded media), the spans need recalculation, risking layout jumps. It’s not really the ideal hack; I’m sure you’d agree.
That’s why this debate matters — our daily grind demands it.
Option 1: Extending CSS Grid For Masonry
One way forward is to strengthen the CSS Grid with masonry powers. As of this writing, CSS grids have been extended to accommodate masonry. grid-template-rows: masonry
is a draft of CSS Grid Level 3 that is currently experimental in Firefox Nightly. The columns of this layout will remain as a grid axis while the row takes on masonry. The child elements are then laid out item by item along the rows, as with the grid layout’s automatic placement. With this layout, items flow vertically, respecting column tracks but not row constraints.
This option leaves Grid as your go-to layout system but allows it to handle the flowing, gap-filling stacks we crave.
.masonry-grid {
display: grid;
gap: 10px;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
grid-template-rows: masonry;
}
First off, the grid-masonry style builds on CSS Grid’s familiarity and robust tooling (e.g., DevTools support). As a front-end developer, there’s a chance you’ve played with grid-template-columns
or grid-area
, so you’re halfway up the learning matrix. Masonry only extends the existing capabilities, eliminating the need to learn a whole new syntax from scratch. Also, Grid’s robust tooling comes along with Chrome DevTools’ grid overlay or Firefox’s layout inspector, removing the need for JavaScript hacks.
Not so fast: there are limitations. Grid’s specifications already include properties like align-content
and grid-auto-flow
. Stacking masonry on the list risks turning it into a labyrinth.
Then there are the edge cases. What happens when you want an item to span multiple columns and flow masonry-style? Or when gaps between items don’t align across columns? The specs are still foggy here, and early tests hint at bugs like items jumping unpredictably if content loads dynamically. This issue could break layouts, especially on responsive designs. The browser compatibility issue also exists. It’s still experimental, and even with polyfills, it does not work on other browsers except Firefox Nightly. Not something you’d want to try in your next client’s project, right?
Option 2: A Standalone Masonry Module
What if we had a display: masonry
approach instead? Indulge me for a few minutes. This isn’t just wishful thinking. Early CSS Working Group chats have floated the idea, and it’s worth picturing how it could improve layouts. Let’s dive into the vision, how it might work, and what it gains or loses in the process.
Imagine a layout system that doesn’t lean on Grid’s rigid tracks or Flexbox’s linear flow but instead thrives on vertical stacking with a horizontal twist. The goal? A clean slate for masonry’s signature look: items cascading down columns, filling gaps naturally, no hacks required. Inspired by murmurs in CSSWG discussions and the Chrome team’s alternative proposal, this module would prioritise fluidity over structure, giving designers a tool that feels as intuitive as the layouts they’re chasing. Think Pinterest but without JavaScript scaffolding.
Here’s the pitch: a display
value named masonry
kicks off a flow-based system where items stack vertically by default, adjusting horizontally to fit the container. You’d control the direction and spacing with simple properties like the following:
.masonry {
display: masonry;
masonry-direction: column;
gap: 1rem;
}
Want more control? Hypothetical extras like masonry-columns: auto
could mimic Grid’s repeat(auto-fill, minmax())
, while masonry-align: balance
might even out column lengths for a polished look. It’s less about precise placement (Grid’s strength) and more about letting content breathe and flow, adapting to whatever screen size is thrown at it. The big win here is a clean break from Grid’s rigid order. A standalone module keeps them distinct: Grid for order, Masonry for flow. No more wrestling with Grid properties that don’t quite fit; you get a system tailored to the job.
Of course, it’s not all smooth sailing. A brand-new spec means starting from zero. Browser vendors would need to rally behind it, which can be slow. Also, it might lead to confusion of choice, with developers asking questions like: “Do I use Grid or Masonry for this gallery?” But hear me out: This proposed module might muddy the waters before it clears them, but after the water is clear, it’s safe for use by all and sundry.
Item Flow: A Unified Layout Resolution
In March 2025, Apple’s WebKit team proposed Item Flow, a new system that unifies concepts from Flexbox, Grid, and masonry into a single set of properties. Rather than choosing between enhancing Grid or creating a new masonry module, Item Flow merges their strengths, replacing flex-flow
and grid-auto-flow
with a shorthand called item-flow
. This system introduces four longhand properties:
item-direction
Controls flow direction (e.g.,row
,column
,row-reverse
).item-wrap
Manages wrapping behaviour (e.g.,wrap
,nowrap
,wrap-reverse
).item-pack
Determines packing density (e.g.,sparse
,dense
,balance
).item-slack
Adjusts tolerance for layout adjustments, allowing items to shrink or shift to fit.
Item Flow aims to make masonry a natural outcome of these properties, not a separate feature. For example, a masonry layout could be achieved with:
.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 setup allows items to flow vertically, wrap into columns, and pack tightly, mimicking masonry’s organic arrangement. The dense packing option, inspired by Grid’s auto-flow: dense
, reorders items to minimise gaps, while item-slack
could fine-tune spacing for visual balance.
Item Flow’s promise lies in its wide use case. It enhances Grid and Flexbox with features like nowrap
for Grid or balance
packing for Flexbox, addressing long-standing developer wishlists. However, the proposal is still in discussion, and properties like item-slack
face naming debates due to clarity issues for non-native English speakers.
The downside? Item Flow is a future-facing concept, and it has not yet been implemented in browsers as of April 2025. Developers must wait for standardisation and adoption, and the CSS Working Group is still gathering feedback.
What’s The Right Path?
While there is no direct answer to that question, the masonry debate hinges on balancing simplicity, performance, and flexibility. Extending the Grid with masonry is tempting but risks overcomplicating an already robust system. A standalone display: masonry
module offers clarity but adds to CSS’s learning curve. Item Flow, the newest contender, proposes a unified system that could make masonry a natural extension of Grid and Flexbox, potentially putting the debate to rest at last.
Each approach has trade-offs:
- Grid with Masonry: Familiar but potentially clunky, with accessibility and spec concerns.
- New Module: Clean and purpose-built, but requires learning new syntax.
- Item Flow: Elegant and versatile but not yet available, with ongoing debates over naming and implementation.
Item Flow’s ability to enhance existing layouts while supporting masonry makes it a compelling option, but its success depends on browser adoption and community support.
Conclusion
So, where do we land after all this? The masonry showdown boils down to three paths: the extension of masonry into CSS Grid, a standalone module for masonry, or Item Flow. Now, the question is, will CSS finally free us from JavaScript for masonry, or are we still dreaming?
Grid’s teasing us with a taste, and a standalone module’s whispering promises — but the finish line’s unclear, and WebKit swoops in with a killer merge shorthand, Item Flow. Browser buy-in, community push, and a few more spec revisions might tell us. For now, it’s your move — test, tweak, and weigh in. The answer’s coming, one layout at a time.
References
(gg, yk)