Embracing CSS Grid

A design system made for layout

Photos from Unsplash

We are finally getting tools designed specifically for modern web layout. New CSS modules are bridging the gap between print and web design. We no longer have the same layout constraints due to new CSS features filling specific needs.

One new feature, in particular, is CSS Grid. The grid layout module provides a native way to easily declare grids. When combined with Flexbox you have a toolset that can solve most frustrations caused by a dependence on tools that clearly weren’t meant for layout.

We all float down here

Traditional tools and techniques available in CSS for layout weren’t intended for the ways in which we use them. Instead, we use floats and have morphed them into fragile and finicky layout systems that require hacks and math in order to get them to work. This has meant — in a lot of cases — people have looked at layout in CSS as frustratingly difficult.

It’s not that CSS itself is hard, instead, it’s the tools and techniques we’ve relied on for layout that has overcomplicated CSS. As a result, we’ve ended up with non-semantic markup and abstruse stylesheets.

Bootstrapping a foundation framework

Responsive design, coupled with these layout struggles, gave rise to an abundance of CSS frameworks and grid systems. While these frameworks helped facilitate rapid development, they also were a crutch developers used to essentially delegate their knowledge of CSS to a prebuilt system. That’s not to say everything about CSS Frameworks are bad. Frameworks have their place, but they became a fixation that were used on every project, no matter the circumstance. As a result, layout on the web became stale due to everything being placed on the same 12-column grid.

The 12-column grid is used for its versatility. It is accommodating of content, mainly distributing it evenly across two, three or four columns. The symmetry of a 12-column grid provides solidity to a layout, but applying the exact same grid to every design isn’t how layout should be approached. Instead, you should design your grid around your content, design, and constraints.

“Don’t be governed by the grid, govern the grid.”
― Massimo Vignelli

Heading in a better flex-direction

Flexbox is an intuitive solution to many perplexing problems in CSS, but it doesn’t solve everything. It has been co-opted as a replacement for float based layouts in a majority of CSS Frameworks. This is a step in the right direction, but while Flexbox is really good at laying out content, it isn’t a tool meant to be used for overall page layout.

Flexbox does a lot of things really well. One of the many things it does well is centering an element both horizontally and vertically. There have been so many “How To” blog posts written on vertical centering, and now, it is painlessly solved with a few lines of CSS. There isn’t a need to use negative margins, negative translates, table-cell or pseudo-elements.

Flexbox is worth the time to learn. As it’s name implies, it’s a much more flexible system than we’ve previously had in CSS. It also results in code that is more maintainable and easier to read.

Opening up another dimension

In March 2017 CSS Grid shipped to Firefox, Chrome, Opera, and both Safari and iOS Safari. In October 2017 Microsoft Edge shipped its support meaning the adoption of this major features shipped to all major browsers this year. As of the publishing of this article current global support (including partial support) for CSS Grid is at 75.34% and will be climbing with Samsung Internet v6.2 coming out of Beta.

CSS Grid allows us to break away from only utilizing rows or columns giving us two dimensions to work with simultaneously. We can declare grids and position elements in both rows and columns, making it an incredibly powerful two-dimensional layout system.

To help you understand why this is powerful, let’s take a look at an example using Flexbox.

One-Dimensional

With Flexbox, when we wrap items and don’t have the same number of items on the subsequent row, we get an undesired result. The content will stretch because Flexbox is only respecting the row. Sure, you could fake a two-dimensional layout by constraining the width of the cards, but once again that would be working for the layout instead of allowing the layout to work for you.

Two-Dimensional

With CSS Grid we don’t have to do a thing. You can have items in both rows and columns and it respects the grid track. While this is a simplistic example, it begins to show you two-dimensional layout with CSS Grid.

Two-dimensional layout becomes obvious if we needed to make the second card span two rows. Good luck doing this with Flexbox. Doing this with CSS Grid takes one line of code.

A defining moment

To create a grid container you apply display: grid to an element. This establishes a new grid context for the contents of the grid container. You can then define an explicit grid using grid-template-columns and grid-template-rows, like so…

.grid {
display: grid;
grid-template-columns: 20% 1fr 1fr 200px;
grid-template-rows: repeat(3, 1fr);

}

It’s perfectly acceptable to mix units when defining the grid. In this code example we have explicitly defined our grid with four columns and three rows. Each value represents the size of the grid track. There are a lot of ways to define explicit track sizing. One of those ways we use in the declaration for row grid tracks. The repeat notation is a compact for of declaring repeated tracks.

That new unit 1fr represents a fraction of the leftover space in the grid container, making the track flexible. When the term track is mentioned, it’s just referring to the column or row of the grid.

Gutters

With CSS Grid you have the ability to define gutters between your row and column tracks. You can define them separately using grid-row-gap and grid-column-gap, or use the grid-gap shorthand property.

.grid {
display: grid;
grid-template-columns: 20% 1fr 1fr 200px;
grid-template-rows: repeat(3, 1fr);
grid-gap: 1em;
}

Placement

Above we positioned grid items using grid-area. We position items by referring to specific grid line — rather than the grid track. Grid lines are given to us when we define grid tracks. Line numbers are based on writing mode and begin at 1.

To position items, I prefer to use grid-column and grid-row which are the shorthand properties for grid-column-start / grid-column-end and grid-row-start / grid-row-end.

.grid {
display: grid;
grid-template-columns: 20% 1fr 1fr 200px;
grid-template-rows: repeat(3, 1fr);
grid-gap: 1em;
}
.item-1 {
/* Item spans one column starting on line 1 */
grid-column: 1;
/* Item spans one row starting on line 1 */
grid-row: 1;
}
.item-2 {
/* Item starts on line 2 and spans 3 grid tracks */
grid-column: 2 / span 3;
/* Item spans one row starting on line 1 */
grid-row: 1;
}
.item-3 {
/* Item spans 2 grid tracks */
grid-column: span 2;
/* Item spans one row starting on line 2 */
grid-row: 2;
}
.item-4 {
/* Item starts on line 3 and ends on line 5 */
grid-column: 3 / 5;
/* Item spans one row starting on line 2 */
grid-row: 2;
}

Named Areas

Another way to define a grid is using grid-template-areas. This provides ASCII art like visuals to your grid definition. Once you have your grid template defined, you can place elements in their tracks by applying the name specified in the definition using grid-area.

.grid {
display: grid;
grid-template-columns: 250px 1fr 1fr 200px;
grid-template-rows: 100px 1fr 75px;
grid-gap: 1em;
grid-template-areas:
"header header header header"
"sidebar content content ads"
"footer footer footer footer";

}
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.content { grid-area: content; }
.ads { grid-area: ads; }
.footer { grid-area: footer; }

You’re on the fast grid track now!

This is only scratching the surface of CSS Grid, but as you can see, we now have real layout tools for the web. There is no more need to think about layout on the web solely as twelve equally spaced columns. We no longer need to rely on grid frameworks for layout, we have a grid framework baked right into CSS that allows us to easily create our own grids.

Embrace CSS Grid. It’s finally here. We now have a layout system that is optimized for design. I urge you to start tinkering with CSS Grid and begin thinking of new design possibilities.