CSS Trivia: Masonry Grid Layout

irrelevantspace

Dalia

Posted on January 14, 2024

CSS Trivia: Masonry Grid Layout

Pinterest's layout has always been the defining feature of the site since its inception. It has been used by many others since then, and I've always been fascinated by it. Recently, I've come to learn that this type of layout is called a Masonry Layout, a name that comes from the craft of stonemasonry. Another thing I've learnt recently is that CSS has an experimental masonry grid layout, with very limited browser support. The specifications are outlined in CSS Grid Layout Module Level 3 Editor's Draft for those who are interested.

A monitor screen showing bricks tightly packed together
(DALL.E's interpretation of a masonry layout)

Creating a Masonry Layout

There are a few different ways to achieve this layout. Horizontal masonry layouts are simpler to create than vertical ones1. You can simply use inline-block elements, or use a flex container with flex-wrap: wrap if you want more control over the layout.

For a vertical layout, flex doesn't do as well unless you have a fixed height container. An approach I like personally is to use columns2. Column layouts are responsive and allow setting the maximum number of columns. The following CSS creates a column layout with a maximum of 4 columns, each column having the ideal width of 180px, and a gap of 10px between columns3.

#column-layout {
  columns: 4 180px;
  column-gap: 10px;
}
Enter fullscreen mode Exit fullscreen mode

The main issue with this approach is that the order of the child elements in the layout is vertical, not horizontal. The example below shows the above CSS in action. Note the order of the elements.

Approaches for a CSS Masonry Layout is a great read on the different ways a masonry layout can be achieved. It covers the cases above and more.

Enter Masonry CSS Grids

So far, CSS grid layout hasn't been flexible enough to create a masonry layout, but this might be about to change. The Editor's Draft introduces a new masonry value to be used for grid-template-columns and grid-template-rows properties. The snippet below creates a responsive vertical masonry grid with columns having an ideal width of 180px, and a gap of 10px between the elements in the grid.

#masonry-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  grid-template-rows: masonry;
  gap: 10px;
}
Enter fullscreen mode Exit fullscreen mode

The result would look something like this:

CSS Masonry grid layout
(CSS Grid with grid-template-rows: masonry)

If your browser supports masonry grids, you can see it in action here:

Examining the result, you'll notice that the order of the elements is horizontal, but they're not exactly in order. The masonry layout algorithm places elements in the columns with the most remaining space to try to achieve an even look for all columns4. If order is important, using masonry-auto-flow: next will place the elements in order, but the final result won't be as even.

CSS Masonry grid layout with ordered elements
(Masonry Grid with masonry-auto-flow: next)

Browser Support and Fallbacks

As of writing this, the masonry value is only supported in Safari Technology Preview5 and in Firefox6 as an experimental feature. If any of the code samples above didn't look right, it might be because the browser you're using doesn't support it yet. If you really want to use it (I know I do), then make sure to provide a fallback for other browsers.

The default fallback when using masonry in an unsupported browser, is to ignore it and use auto instead. This example shows what the fallback would look like.

If that's not the look you're going for, you can detect support for the masonry value using @supports and provide alternative CSS for unsupported browsers. Here's how to fallback to the column layout we saw earlier.

#masonry-layout {
  columns: 4 180px;
  column-gap: 10px;
}

@supports (grid-template-rows: masonry) {
  #masonry-layout {
    columns: auto;
    column-gap: 0;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    grid-template-rows: masonry;
    gap: 10px;
  }
}
Enter fullscreen mode Exit fullscreen mode

For a live example, my personal website falls back to a hacky flex layout if the browser doesn't support masonry grids.

CSS Masonry grid layout
(The masonry grid in action)


  1. Google Images layout is an example of a horizontal masonry layout, while Pinterest is an example of a vertical one. 

  2. A multi-column CSS layout, flows an element's content into columns. 

  3. The column-gap property only applies to the space between columns, not between rows (as the name might suggest). The space between rows can be set using margin on the child elements. 

  4. The algorithm is explained in more detail in the editor's draft 

  5. Enabled since version 163. See the release notes 

  6. Available since version 77 and enabled by default in Nightly. Can be enabled from about:config by setting layout.css.grid-template-masonry-value.enabled to true. See the release notes 

💖 💪 🙅 🚩
irrelevantspace
Dalia

Posted on January 14, 2024

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related