My fellow CSS developers,

I know you’ve been burned before with tales of exciting new CSS specifications that won’t be ready to use in production for years. I’m here to tell you, those days are in our past and the brightest example of our future is with CSS Grid! You can absolutely use it now, and in this article, I’ll show you how without much fuss or the need for any external dependencies.

The backstory: How CSS Grid went from 0 to approximately 70% browser support in under a month

Before we dive into the “how”, let’s better understand a little of the “why” Grid is different than the CSS features that have come before.

In early 2017, three major browsers, Firefox, Chrome, and Safari, shipped unprefixed and consistent Grid implementations within weeks of each other. This approach is drastically different from how Flexbox was rolled out, and this was intentional to avoid all the drama we developers have had to deal with (and still have to deal with) around vendor prefixing. Grid was worked on behind browser flags instead of being rolled out with vendor prefixes so it could still be tested, but could not be used on production sites while it was being developed and iterated on. So unlike Flexbox, Grid has been delivered prefix-free and ready to use from the onset… with one small exception.

The origin of the Grid specification came from Microsoft and this early version has been live in Microsoft browsers with an -ms prefix since Internet Explorer 10 in 2012. The specification has grown considerably since these early days, with new properties and values that were not part of the original specification. The key thing to remember from this is that vendor prefixed Grid properties mean old Microsoft specification, and there are no prefixed versions that exist in any other browsers. Later on, I’ll talk about what that means and how to easily get around it so the old prefixed version does not cause unintentional layout problems.

A step by step guide to writing CSS Grid

I have been confidently writing Grid for use in production since November of 2016, before it had shipped in any browser. Here’s how I go about it:

Identify a good use case for Grid

Is it worth the hype? What exactly is Grid and what is it good for?

Grid is awesome! It can create layouts that we couldn’t achieve with pure CSS before, and it can make layouts we already have much easier to write and maintain without frameworks. This of course, is not going to be the right solution for every problem and it is not a replacement for Flexbox, although it shares a lot of the same traits.

Flexbox is great for laying out elements in one direction.

Either in rows…

…or columns.

Grid allows you to layout elements in two directions, columns and rows!

The major benefit here is that we don’t need elements to depend on each other for placement. We can specify their position on the x and y axis independent of what is around them.

Think of the possibilities! There are already so many terrific resources out there for how to use Grid. Two sites I recommend for in-depth tutorials and examples of Grid are by Jen Simmons at labs.jensimmons.com and Rachel Andrew at gridbyexample.com. Rachel has also created a great guide to getting started: gridbyexample.com/learn.

Now that we have a bit more history and background, let’s look back at the original question: when should I use Grid? I consider it whenever I would normally reach for a different common layout property: either Flexbox, floats, or positioning, and then play around with Grid to see if I can make it work. What I have found is that most of the time, Grid makes things much more simple and I end up learning a lot about how the new specification works in the process.

Write Grid code

Make sure you are working with a browser that supports Grid, which as of this publication is the latest versions of Chrome, Safari, and Firefox, with Edge support coming on 17 October 2017. If you aren’t sure, check Can I Use? for a list of supported browsers.

For the rest of this article, we’ll use an example implementation of Grid from a side project of mine, Grub Gallery, a single page app that displays Foursquare search results as images.

This is a pretty straight forward use of Grid: display images of equal width and height in rows and columns.

Here’s the markup we will style (I’ve simplified the markup so we can focus only on what we are working with):

<ul class="search-results">

<li class="search-results__result">

<img class="search-results__photo" src="path-to-image.jpg">

</li>

<li class="search-results__result">

<img class="search-results__photo" src="path-to-image.jpg">

</li>

...more <li>s

</ul>

Here’s the CSS using Grid:

.search-results {

display: grid;

grid-gap: 10px;

grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));

padding: 10px;

}

Yes, that’s all we need! Four properties on the parent element to make this layout fully responsive, flexible, and fluid. This code is saying, “I want the children of .search-results to be in a grid with 10px gutters between each element, and 10px around the edge of their container. Each element should be no smaller than 320px, but go ahead and size them larger to fill the width of their container evenly until you can fit another element in the row at 320px.”

Here’s an article with a more detailed explanation on auto-fit and minmax. Rachel Andrew also has a great in-depth video tutorial on the fr unit.

Fallback gracefully with CSS @supports

We can use @supports in our CSS to perform a feature query, and wrap our grid code in a rule like this:

@supports (display: grid)

.search-results {

display: grid;

grid-gap: 10px;

grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));

}

}

These styles will now only be read by browsers that support the display: grid; property. Every browser that supports Grid also supports @supports , so if a browser doesn’t know how to read @supports , it will ignore what’s inside of it. For this reason, we should make our fallback styles our default CSS styles to cover all cases.

Since you are working in a browser that supports Grid, comment out the Grid styles while you write your fallback styles to be able to test them in your browser, and don’t forget to uncomment them out when you are finished.

Here is my final code with Flexbox as a fallback and my Grid styles wrapped in an @supports rule. Make sure to put your Grid styles after your default fallback styles. This way you can override any styles from the fallback that aren’t needed for Grid. In the following example, I originally didn’t need any styling on the child .search-results__result elements with my Grid-only solution, but after writing the fallback, I needed to override the default styles for margin and width. Look at all those media queries I had to add with my fallback that I didn’t need with Grid!

.search-results {

display: flex;

flex-wrap: wrap;

padding: 5px;

}

@supports (display: grid) {

.search-results {

display: grid;

grid-gap: 10px;

grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));

padding: 10px

}

}

.search-results__result {

margin: 5px;

}

@media only screen and (min-width: 500px) {

.search-results__result {

width: calc(50% - 10px);

}

}

@media only screen and (min-width: 800px) {

.search-results__result {

width: calc(33.3333% - 10px);

}

}

@media only screen and (min-width: 1200px) {

.search-results__result {

width: calc(25% - 10px);

}

}

@supports (display: grid) {

.search-results__result {

margin: 0;

width: auto;

}

}

Considerations with Autoprefixer

With the above approach, you have all bases covered with a fallback for browsers that don’t support Grid. The @supports (display: grid) rule will not apply to browsers that support only the prefixed version of grid (Internet Explorer). However, if you use Autoprefixer as a post-processor and you are using the method above, you most likely don’t want it to translate Grid for you. It’s easier to have Internet Explorer rely on your fallback, so you need to make sure that Autoprefixer has Grid disabled.

If you are using Autoprefixer version 7.0 or above, Grid is disabled by default and you don’t have to do anything! If you are using an earlier version of Autoprefixer, either upgrade to version 7.0 or above, or you can set grid: false in your Autoprefixer configuration. Where that configuration occurs varies depending on how you are serving it (Webpack, Gulp, Rails, etc).

Ship It!

Yes, that’s all! No JavaScript, no polyfills, no frameworks, no fuss, not much extra time to implement. I find it generally takes me longer to write the fallback than to write the Grid code (I told you it was awesome!).

Super graceful degradation

In our example, we are accomplishing practically the same layout with Grid or with Flexbox, but that doesn’t have to be the case. CSS doesn’t have to be all or nothing anymore. Let’s push the boundaries forward! We have been conditioned to strive for pixel perfection, but we’ve had the world of responsive design and unlimited device widths to consider for a few years now. I encourage you to optimise for the best experience in modern browsers (right now, over 70% usage globally for Grid and climbing!) and to provide a great, usable experience for the rest.