How to use and feature-detect CSS grid masonry layout
Tags: css, webdev
Published: 2021-02-14 19:18:32

---
title: How to use and feature-detect CSS grid masonry layout
published: true
description: How to apply and adopt CSS-only masonry grid layout with fallbacks and feature detection in CSS and JavaScript.
tags: css, webdev
canonical_url: https://www.stefanjudis.com/blog/how-to-use-and-feature-detect-css-grid-masonry-layout/
---

[The very new CSS masonry Layout functionality coming with CSS grid](https://drafts.csswg.org/css-grid-3/) will ship in browsers eventually. 

This post shares what you need to do to get started and implement masonry layout in your sites, and it explains feature detection in CSS and JavaScript. It's not going into the nighty-gritty details of masonry grid layouts. If you want to dive into the topic, find additional resources at the end of the article.

That's [my site's implementation for browsers that do or don't support the new masonry grid layout](https://www.stefanjudis.com/today-i-learned/).

![Comparison of the today i learned section on stefanjudis.com with and without masonry support](//images.ctfassets.net/f20lfrunubsq/1W11zzLnIB0sFCHr1gbU8n/1dc48625e06cc10f051a48ef88fb8441/Screenshot_2021-02-14_at_14.27.32.png)

On the left, you see a standard CSS grid layout. Unfortunately, the content in the grid has one problem. The included sections and areas substantially vary in height. Some elements hold only a few entries whereas others include more than thirty entries. Having these sections next to each other in a grid leads to a lot of empty whitespace. That's why I manually adjusted particular cells to span over multiple columns.

For example, the area for `CSS` spans over three rows using `grid-row: auto/span 3`. Similar to most manual adjustments, this is far away from being perfect. 

```css
.area-css {
  grid-row: auto/span 3;
}
```

In these situations the masonry grid layout comes into play and shines. It enables you to make the best out of all the available space without manual adjustments. 🎉

One the right, the elements for each area are automatically readjusting depending on their height. The grid is laid out automatically. __It's beautiful!__ 

The masonry grid is based on CSS similar to [the snippet you find in the MDN documentation for CSS grid with Masonry](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout/Masonry_Layout). 

```css
.container {
  display: grid;
  gap: 10px;
  grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
  grid-template-rows: masonry;
}
```

The code above leads to a grid similar to my site and the one below.

![Masonry grid example](//images.ctfassets.net/f20lfrunubsq/1FhT1cOzzx6XO2jJTUl66j/a3f0db47687a7e3444f841e742ac4c8e/Screenshot_2021-02-14_at_17.38.53.png)

## CSS masonry is not cross-browser supported yet

First things, first. At the time of writing, there's no cross-browser support for masonry grid layout. When you're looking at [caniuse.com for the masonry layout](https://caniuse.com/mdn-css_properties_masonry), you'll find out that there's no browser at all. No browser is shipping masonry layouts, and it's only Firefox rushing ahead with an implementation behind a flag.

![caniuse.com support table for Masonry layout showing no support except Firefox with a behind-a-flag implementation](//images.ctfassets.net/f20lfrunubsq/58tg0AKm7jgLu7hGv5dFVu/896bfd24572acd56cc34662f5599ae07/Screenshot_2021-02-14_at_17.21.11.png)

To get started, open Firefox and open `about:config` (you can type it into the URL bar) and enable the boolean flag for `layout.css.grid-template-masonry-value.enabled`.

![about:config screen with enabled masonry config option](//images.ctfassets.net/f20lfrunubsq/65oXXHtqfUuxk4qpNrMevq/9657559c8672b638a7731cfed091d022/Screenshot_2021-02-14_at_14.36.57.png)

Once you enabled masonry grid layout, head over to [my TIL overview](https://www.stefanjudis.com/today-i-learned/). A celebration message, confetti and the masonry grid layout spanning the whole page will greet you.

![Screenshot of the site: "Looks like your browser supports masonry grid layout... Cool beans!"](//images.ctfassets.net/f20lfrunubsq/5J4Na6DL0NF7eqpByjhs8C/3ec8258c18f3b5dc576ae79ede84a51b/Screenshot_2021-02-14_at_14.34.02.png)

## Feature detection of new CSS features such as masonry grid layout

There's one critical fact about web platform feature adoption. You can't just throw new and only partially supported features into your CSS and call it a day. You always have to consider a fallback behaviour. 

Is the new feature degrading gracefully? Does everything still work when the browser doesn't support it? Is the new web platform feature mission-critical or is just fine, if it doesn't work?

These questions are essential to guarantee a good user experience, and that's why my site includes feature detection in CSS and JavaScript to define a fallback behaviour.

### Feature detection in CSS

To check if a browser supports a new CSS feature, leverage [the `@supports` feature query](https://hacks.mozilla.org/2016/08/using-feature-queries-in-css/). Use the feature query with the CSS declaration you want to test and apply your CSS if a browser does or does not support the new CSS feature.

I added a new class (`list-masonry`) to my code base that should apply the masonry layout if the browser supports it.

```css
/* define list-masonry if the browser support Masonry */
@supports (grid-template-rows: masonry) {
  .list-masonry {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    grid-gap: var(--grid-gap);
    grid-template-columns: repeat(auto-fill, minmax(16em, 1fr));
    grid-template-rows: masonry;
  }
}
```

Additionally, to hide and show the celebration message, I added a new utility class. The class works similar to classes such as `hide-on-small` that hide elements depending on viewport sizes.

The difference to viewport dependent classes is that `show-if-supports-masonry` doesn't rely on a media query but a feature query.

`show-if-supports-masonry` initially sets the element's `display` property to `none`. If a browser supports masonry layout, the feature query overwrites the "hiding CSS" with `display: block`.

```css
/* hide element initially */
.show-if-supports-masonry {
  display: none;
}

/* show elements if the browser support masonry layout */
@supports (grid-template-rows: masonry) {
  .show-if-supports-masonry {
    display: block;
  }
}
```

Paired with the following HTML, I can show a celebration message depending on the browser feature support.

```html
<div class="show-if-supports-masonry">
   🎉 Looks like your browser supports masonry grid layout... Cool beans! 🎉
</div>
```

### Features detection in JavaScript

So far, I applied the masonry grid layout and showed a nifty message when it was supported. But I wanted to celebrate the early adopters even more!

The people who are browsing my site and maybe even subscribed to [my newsletter](https://www.stefanjudis.com/newsletter/) might know that I have confetti canons in several areas on my site.

*Little quick trick:* You can add confetti to your site without any tooling by leveraging [skypack](https://www.skypack.dev/). Skypack is a CDN for JavaScript packages that expose ES modules. To add a confetti canon to your site, all you have to do is:

- add a `<script type="module">` to your site to able to use `import` statements
- load the `confetti-canvas` module from Skypack using `import confetti from 'https://cdn.skypack.dev/canvas-confetti'` or `import('https://cdn.skypack.dev/canvas-confetti')`
- throw confetti by calling `confetti()`

Skypack and ES modules are fantastic and I find myself adding these tiny code blocks more and more these days.

```html
<script type="module">
  // load and display confetti
  // if masonry grid layout is supported
  if (CSS.supports("grid-template-rows", "masonry")) {
    import('https://cdn.skypack.dev/canvas-confetti')
      .then(({default: confetti}) => confetti())
  }
</script>
```

The interesting part of this confetti snippet is the CSS feature detection using [`CSS.supports`](https://developer.mozilla.org/en-US/docs/Web/API/CSS/supports). It allows you to handle not supported CSS features in JavaScript. If a CSS feature is necessary to your site, you could load polyfills or offer an alternative experience.

I love the web and its features these days!

## Summary

That was it to implemented CSS grid Masonry on my site. The not-supporting browsers are showing the grid with cells spanning over several columns. That's good enough for my site!

On the other hand, the site includes confetti and a grid that's not wasting and screen space for supporting browsers.

And all this functionality is feature detected using `@supports` in CSS or `CSS.supports` in JavaScript. 🎉


### Additional resources

- [CSS Grid Layout Module Level 3](https://drafts.csswg.org/css-grid-3/)
- [Native CSS Masonry Layout In CSS Grid by Rachel Andrew](https://www.smashingmagazine.com/native-css-masonry-layout-css-grid/)
- [Masonry Layout on MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout/Masonry_Layout)