CSS Grid and Masonry Layout

Ebisucom
6 min readApr 30, 2024

A comparison of masonry created with CSS Grid Level 1, Level 3 or display: masonry

The “Masonry Layout,” which looks like stacked stones and is familiar from sites like Pinterest, was proposed as CSS Grid Level 3. Although It received experimental support in Firefox in 2020 and later in Safari Technology Preview in early 2023, progress on this feature has been halted.

The recent WebKit article addresses this issue. It poses the question of whether Masonry should be a part of CSS Grid or implemented as a new layout mode through display: masonry.

Help us invent CSS Grid Level 3, aka “Masonry” layout | WebKit
https://webkit.org/blog/15269/help-us-invent-masonry-layouts-for-css-grid-level-3/

There seem to be some concerns like “Is Masonry a grid layout?”, “Masonry makes CSS Grid more complex”, etc.

However, creating common masonry layouts using CSS Grid is quite simple. Let’s compare a regular grid layout with one that uses the masonry functionality.

  • Chrome and Edge don’t support this feature yet.
  • In Safari Technology Preview, masonry layouts are enabled by default, so you can check them out without any extra steps.
  • In Firefox, you’ll need to enable a flag (an experimental feature). Type about:config in the address bar, and set layout.css.grid-template-masonry-value.enabled to true.
Firefox setting

Difference Between Regular Grids and Masonry Grids

Creating Masonry-Like Layouts with the Standard CSS Grid Level 1 Features

You could create “something like a masonry layout” using the existing CSS Grid features.

by using grid-template-columns: repeat(auto-fill ...), you can create a grid with several columns that adjust based on the screen width, and automatically place images in the grid. For portrait-oriented images, use grid-row: span 3 to make them span 3 rows, resulting in a layout like this:

Masonry Layout using CSS Grid Level 1 (Modular Grid) in Firefox, including the grid structure and line numbers.
【CodePen】
.grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 16px;

img.portrait {
grid-row: span 3;
}

img {
width: 100%;
height: 100%;
object-fit: cover;
}
}

In this code, we don’t specify the row configuration grid-template-rows. The rows are automatically generated based on the number of columns and images, and the images are automatically placed into the resulting cells.

Of course, not all images will fit the cell they’re placed in. To handle this, we set the image’s width and height to 100%, and use object-fit: cover to crop them. This means their original aspect ratio is not preserved, making it an imperfect masonry layout.

On the other hand, the images are aligned along the horizontal lines formed by the rows. It gives a crisp, structured appearance and is well-suited for such as Bento UI.

This type of row/column-based grid is referred to as a “Modular Grid” in the WebKit article.

Creating Masonry Layouts with the CSS Grid Level 3 Masonry Features

To create a masonry layout, you simply need to set grid-template-rows: masonry. With just that, the images will be arranged in a masonry pattern like this:

Masonry Layout with CSS Grid Level 3 (Columnar Grid) in Firefox
【CodePen】
.grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
grid-template-rows: masonry;
gap: 16px;

img {
width: 100%;
height: auto;
}
}

The key feature is that the grid rows are not structured. This allows images of different aspect ratios to fit and align seamlessly without crops. Since there are no rows, the images are not aligned horizontally, but that’s what I want.

This type of grid, composed solely of columns, is referred to as “Columnar Grids” in the WebKit article.

What’s the Problem?

The masonry setting is so simple. It’s just with a grid-template-rows: masonry. It seems like there shouldn't be any issues. However, there are some concerns, such as compatibility with the many existing CSS Grid features and making the grid even more complex.

For example, what happens when column widths vary, when mixing fixed and flexible sizes, when specifying row/column spans for images, when placing images in specific locations, when the specified locations don’t exist, how it interacts with line, area, justify, align, position, and so on and so on…

Even the CSS Grid Level 1 and 2 features are not yet fully utilized. Now with Level 3, masonry features have been added, and the underlying algorithm is becoming more complex.

So there’s a discussion it would be simpler to make the masonry independent as display: masonry.

display: masonry would simplify things, but…

If display: masonry is adopted, we wouldn't be able to use many of the "convenient" CSS Grid features, or we'd have to wait for their implementation.

It would be fine if we didn’t use those features. But just like how we ended up wanting the gap utility from Flexbox after the fact, we can't rule out the possibility of wanting "that grid feature..." down the line.

In the demos from the WebKit article, a typical masonry layout with uniform column width is referred to as “Classic masonry”. On top of that, the showcase has various layouts combining the convenient CSS Grid features like varying column widths or newspaper-style layouts.

From the demos in the WebKit article. Left to right: Classic masonry, Alternating narrow & wide columns, Newspaper: Various size of content.

On the GitHub

On the GitHub issue, the majority opinion is that masonry should be part of the CSS Grid features. Even the author of the Masonry JS library commented:

In my experience, the vast majority of users want uniform column width. CSS grids provide so much power over layout with track sizing. I think that amount of customization over the tracks is an unwanted feature when working with masonry layouts. Typically with a masonry layout, you want the item to have the same size regardless of its position in the grid. So, if you want to be practical, go with display: masonry, this will satisfy 95% of masonry layout usage.

“display: masonry” vs “grid-template-rows: masonry”

Having said that, grid-template-rows: masonry maps to my mental model of how Masonry works, now that CSS grid is an established convention.

https://github.com/w3c/csswg-drafts/issues/10233#issuecomment-2070148836

Conclusion

There are valid points for both approaches: making it part of CSS Grid or using display: masonry .

However, realizing that grid-template-rows: masonry just creates a grid without rows” has made me naturally accept it as part of CSS Grid.

If masonry becomes a part of CSS Grid, it could simplify the learning process and offer more layout possibilities. This even leads me to wonder, why not implement multi-column layouts through CSS Grid as well?

And I’m interested in the “CSS Grid Level 4” that was mentioned in the WebKit article:

many developers want CSS Grid Level 4 to provide a mechanism for styling grid areas and grid lines — perhaps a way to add a background color to a track, or create a rule line in a gap.

It seems like CSS Grid still has a lot of room for growth and development. While looking forward to its future evolution, I want to keep actively utilizing and taking advantage of CSS Grid’s capabilities.

--

--

Ebisucom

Front-end / design / HTML / CSS / Next.js / Astro.js / WordPress / etc. Technical book writing. English: https://ep.ebisu.com/en Japanese: https://ebisu.com