DEV Community

Cover image for CSS Trivia: Masonry Grid Layout
Dalia
Dalia

Posted on • Originally published at ir.relevant.space

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 

Top comments (10)

Collapse
 
jonrandy profile image
Jon Randy 🎖️

Never understood why anyone thought this layout was a good idea. Really difficult to scan with your eyes

Collapse
 
leob profile image
leob

I think this in the vein of "sometimes we just want something which isn't really functional, but which looks cool" ;-)

Collapse
 
irrelevantspace profile image
Dalia

Absolutely. Also why does this sound like the motivation behind every side project I work on :D

Collapse
 
irrelevantspace profile image
Dalia

I find it quite visually appealing, but you make a very good point. I'd think the amount and type of data presented need to be considered when choosing such a layout.

Do you think a horizontal masonry layout (e.g. Google Images) is easier to scan or is the same?

Collapse
 
jonrandy profile image
Jon Randy 🎖️

Horizontal works much better

Collapse
 
solfkwolf profile image
solfKwolf

Because some people want to see more cards at once and pick something they're interested in

Collapse
 
dev_geos profile image
Dev Geos

This one can be made easily with flexbox or not ?
I will try it

Collapse
 
irrelevantspace profile image
Dalia

It can if you don't mind vertical ordering of the items and I think you'd need a fixed height layout, but that's only if you're making a vertical (Pinterest style) layout. Let me know if you end up trying it!

Collapse
 
dev_geos profile image
Dev Geos

I think too. I will tell you after

Collapse
 
lesliele profile image
leslie_kai

cool