CSS Grid Layout

August 30, 2017 | Jordan Brauner

man behind grid of string with spool of stringThe level 1 specification of CSS Grid Layout (aka “Grid”) has been out in the wild for a few months, but some uncertainties persist about the problems it solves, how it can be integrated into our workflow, and whether it’s safe to ship. Personally speaking, after digging into the documentation and playing around with dozens of examples, I still encountered some challenges wrapping my head around specific use cases for two-dimensional layouts. I hope the examples I present here will be helpful for others who have little-to-no hands-on time with the new layout system and are wondering why they should use it as opposed to alternatives such as Flexbox.

Before I jump in, it’s important to note that two of the most prominent voices on Grid, Jen Simmons and Rachel Andrew, have done excellent work detailing this new layout system as well as engaging the community and fostering discussion of where Grid and Web design will go from here. I’d highly recommend going through their many articles, presentations, live examples, and walkthroughs when you’re ready for a more thorough deep dive into all things Grid.

What is CSS Grid Layout?

At its core, Grid is all about efficiently creating two-dimensional layouts natively in CSS (no JavaScript libraries required). Whereas Flexbox is one-dimensional and restricted to displaying content in rows or columns, Grid allows you to arrange items in a true two-dimensional grid using rows and columns (aka “tracks”, but more on that in a bit). Additionally, you can use Grid to lay out the structure of an entire page or only use it when you feel a specific component would benefit.

A common misconception amongstWeb developers is that Grid is meant to replace other layout systems such as Flexbox, but that is not the case. If you have no need to align a group of items in two dimensions, and you’re not overriding the responsive behavior of flex-basis with a percentage, then Flexbox may be the better choice. Flexbox is also a better fit for aligning content inside a container.

Grid is not an either-or situation, you can use it with Flexbox and has been designed as such. For example, you can use Grid to structure the main items on a grid and then use Flexbox to align the content inside each item, or you could use Flexbox to align each grid item within its tracks on the grid.

The Basics of Grid

Before I explore a few different scenarios in which Grid can be useful let’s start with a simple example that serves as a brief introduction to a few of the core Grid properties.

See the Pen CSS Grid - Simple Grid by Jordan (@tbgjab) on CodePen.

Here is a fluid grid with seven items of equal width and height. I’ve explicitly defined three column tracks using the `grid-template-columns` declaration, each the size of 1 fraction unit (aka “fr”). I’ve then given the grid a gutter of 1em to pad out the grid lines between the tracks. (Fraction units represent the remaining size available in the track after any tracks with fixed sizes have been placed. For example, if the first column is `200px` and the second and third are `1fr`, the first column would be placed and then the remaining space on the track would be evenly distributed between the second and third columns.)

Grid took the value of the `grid-template-columns` declaration and then laid out grid items in one row across three equally sized columns and then implicitly created additional row tracks as needed to place the remaining items. Note that while there are only seven grid items, the bottom row still contains three 1fr column tracks, thus ensuring the seventh item is the same width as the other items in its column.

Scenario 1: Two-Dimensional Column-Flowing Grid

Let’s say you’re building a multi-column list of links. You’re told to expect some outlier variations in the length of the anchor text and it’s a requirement that the links be placed column by column instead of in rows.

You may decide to tackle this with Flexbox and use `flex-direction: column`, but in doing so you’d still be lining up the items in one dimension. For example, when the anchor text of an item wraps, it would push down the items below it, disrupting the vertical alignment of the items to their sides. Fortunately, this is a task Grid excels at.

See the Pen CSS Grid - Reponsive 2D Column-Flowing Grid by Jordan (@tbgjab) on CodePen.

With only a few declarations adjusted at different breakpoints, I’ve easily solved the problem with Grid. The column-flowing content now maintains its vertical alignment across rows no matter the length of the anchor text.

For the largest media query, I’m using the repeat notation for `grid-template-rows` to create six rows 1fr in height. The `grid-auto-flow: column` declaration (default is row) flows the content in columns. I then increased the row count at the medium size breakpoint so that the grid implicitly creates two columns instead of three. For mobile, I only define one column track and let Grid’s auto-placement default to row.

It’s worth mentioning that this particular solution does require a rough estimate of the maximum number of items you plan to allow on the grid. Column flowing content needs a set number of rows so that Grid knows when to create the next column. Fortunately, it’s forgiving and I’d wager that at least half of the time you’d have an item limit in mind before you start building.

Scenario 2: Masonry

With this next example we’ll look at how easily Grid can style a masonry-like layout. Typically, when Web developers are tasked with building a two-dimensional layout, we’d probably reach for a JavaScript library such as Masonry.js to expedite the process. Libraries like Masonry.js are not a bad option by any means, but with Grid we can now handle this natively in CSS without additional JS calls and without the need for additional files to be downloaded.

See the Pen CSS Grid - Responsive 2D Grid with Featured Items by Jordan (@tbgjab) on CodePen.

Here, I’m using only 8 CSS Grid declarations to build a responsive grid with two types of featured items. Let’s go through these declarations line by line.

After setting the display of the container to grid, I explicitly create the columns with `grid-template-columns: repeat( auto-fill, minmax(160px, 1fr) )`

I used the repeat notation in the previous example, and here we are now incorporating auto-fill and minmax. Auto-fill tells Grid to create as many tracks as needed to fit the container. Minmax takes a minimum and maximum size for the track. I’ve specified a minimum of 160px and a maximum of 1fr. This declaration places as many 160px columns as possible, and any remaining space in that track will then be evenly distributed between them.

Wrapping your head around grid-auto-flow can be a little more complicated. If I did not specify `grid-auto-flow: dense`, Grid’s auto-placement algorithm would place each item in order until it reached an item that spans more than one column and extends beyond the boundaries of the grid (e.g. the last column). At that point, if this particular item happens to land in the last column, it would be moved down to the first column in the following row, leaving a gap in the last column of the preceding row while Grid continued on to the column to the right of the featured item. With `grid-auto-flow: dense`, auto-placement properly pulls the next item that can fit into the empty spot and places it there before moving on to the next empty area.

Finally, the modifier classes for the featured items alter the number of rows and/or columns the item spans. I’m using the `grid-column` and `grid-row` declarations to specify the number.

The Power of Grid!

If you’ve been hesitant to use Grid because you’re overwhelmed by learning a new layout system with nearly 20 new properties, keep in mind that while Grid is powerful, you can do a lot using just a few of its main properties. Start small and snowball. If you’ve been holding off on using it because you are concerned the spec could significantly change in six months (see Flexbox), know that Grid has been in the works for years and was not released half-baked.

What about browser support? As of the publication of this article, support for the level 1 specification is strong. You can use it in Chrome, Safari, Firefox, and Opera unprefixed. Edge is expected to support the level 1 specification sometime this year. In the meantime, both IE10+ and Edge support the older specification for Grid. If learning both specs for Grid is not in the cards then one possible solution would be to use Modernizr or CSS feature queries to enhance float or flexbox-based layouts with Grid.

It’s clear that CSS Grid has the potential to enhance our designs as well as drastically change how we create layouts. While I mainly focused on small-scale examples for individual components, Grid is also built to handle entire page layouts. For many years, we’ve been using floats to lay out content in ways never intended. With Grid and Flexbox, we have tools designed for our current needs and beyond. It may still be many months before we see widespread adoption and many more before we begin to see entirely new layout designs that use the full potential of Grid, but why wait when we can lead the way today as early adopters of this innovative new layout system!

Recommended Reading

CSS Grid Layout Level 1 Specification

CSS Grid Layout - MDN

Grid by Example - Rachel Andrew

Learn CSS Grid - Jen Simmons

About the Author

Jordan B
Jordan Brauner

I’m a Front End Developer at TBG. When I’m not coding I’m dreaming about rainbow cake, going to the zoo with my family, or brushing up on my table tennis skills in VR.

Leave A Reply

comments powered by Disqus