CSS Grid Areas are amazing
Tags: css, grid, web, tutorial
Published: 2018-12-31 18:50:52

---
title: CSS Grid Areas are amazing
published: true
description: "Let me tell you about the thing that completely convinced me of the power of CSS Grid Layout: Grid Areas!"
tags: css, grid, web, tutorial
series: CSS Layout is Awesome
---


When I first learned about CSS Grid Layout and the new powers it gave us as CSS developers, I was immediately excited. I was thrilled at the prospect of shedding all those layers of non-semantic container `div`s needed for a Bootstrap or Foundation grid, replacing them with purely semantic HTML documents and leaving the layout completely to CSS, as it always should have been.

But when I would talk to other developers who weren't as hyped about semantic markup, the response I often received was, "I already know how to do a grid system with <grid library x>, and I don't really want to learn a whole new thing right now... am I really going to gain something practical here, or will I just arrive back where I started, but in a different color car? **What can I do with CSS Grid that I can't already do with a basic grid system?**"

Today I want to answer that question with two words: *Grid Areas*.


# Tracks and Lines

In CSS Grid Layout, a grid is made of **tracks** and **lines**. "Track" is the generic term for a row or column. As you might have guessed, "lines" are the boundaries between the tracks. We define our grids in terms of tracks with  [`grid-template-rows`](https://developer.mozilla.org/en-US/docs/Web/CSS/grid-template-rows) and [`grid-template-columns`](https://developer.mozilla.org/en-US/docs/Web/CSS/grid-template-columns), then we attach our grid items to our grid in terms of lines with [`grid-row`](https://developer.mozilla.org/en-US/docs/Web/CSS/grid-row) and [`grid-column`](https://developer.mozilla.org/en-US/docs/Web/CSS/grid-column).

![Grid tracks and lines](https://thepracticaldev.s3.amazonaws.com/i/dwev3ij08w5xcamxe04t.png)

For many cases, perhaps most, tracks and lines are all you need to define your grid. Especially for smaller areas with dynamic content, like a grid of search results or a friends list, you can often just use `grid-template-columns` to define your columns, use [`grid-auto-rows`](https://developer.mozilla.org/en-US/docs/Web/CSS/grid-auto-rows) to declare how tall new rows should be, and let CSS Grid's wonderful auto-placement behavior fill out your grid for you from there.

{% codepen https://codepen.io/kenbellows/pen/ebeMgB %}

But sometimes things aren't that dynamic. Sometimes you have a predefined, fixed set of items to lay out in your grid, you know exactly where you want them to go, and you just want to hand the browser the correct answers, no auto-placement magic for you. This is very common when using a grid to lay out the top-level structure of a site: header goes here, navbar here, profile picture over there, content over here, done.

You can definitely still define everything by specifying your tracks fixing blocks to line numbers, and this is very common. For example, suppose you were coding up a simple user profile with four sections: a display name, an avatar, an "about" section, and a list of posts the user had made. You might do something like this:

```html
<main>
  <h1 class="display-name">...</h1>
  <section class="avatar"><img src="..."></section>
  <section class="about">...</section>
  <section class="posts">...</section>
</main>
```
```css
main {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
}
.display-name {
  grid-row: 1 / 2;
  grid-column: 3 / 6;
}
.avatar {
  grid-row: 1 / 3;
  grid-column: 1 / 3;
}
.about {
  grid-row: 3 / 4;
  grid-column: 1 / 3;
}
.posts {
  grid-row: 2 / 5;
  grid-column: 3 / 6;
}
```

{% codepen https://codepen.io/kenbellows/pen/jXazZq %}

The [`grid-template-columns`](https://developer.mozilla.org/en-US/docs/Web/CSS/grid-template-columns) rule for the grid container defines our column tracks, and the [`grid-row`](https://developer.mozilla.org/en-US/docs/Web/CSS/grid-row) and [`grid-column`](https://developer.mozilla.org/en-US/docs/Web/CSS/grid-column) rules for the grid items specifies which grid lines should be the boundary for each item.

And this definitely works. But there are some frustrations here:

* Staring at a bunch of numbers can make your grid hard to visualize, and I often end up doing a lot of fiddling with those line numbers to get things looking right. This isn't an issue specific to CSS Grid, and tbh it's a lot easier than fiddling with padding and margins and float values and `flex-grow`, but it's still worth noting.
* What if I want to add a new track or item later in between the existing tracks or items? I'll probably have to update a bunch of those line numbers up there. You could use the `span` keyword instead of a hard line number for the column- and row-end values, so you're specifying how many tracks to cover rather than which grid line to stop at, but that's a trade-off; sometimes it helps, sometimes it gets in the way.
* There's a lot of repetition up there. Related to the previous point, if you just want to add a column on the left for, say, a sidebar, you'd have to find all instances of `grid-row: 1 / ...` and update each 1 to a 2. This gets worse in more complex layouts.
* Responsive layouts with media-query breakpoints that shift things around can be a bit verbose and confusing, since you need to specify all these values for each breakpoint, which sort of compounds the issue of visualizing each different layout.

Thankfully, the writers of the CSS Grid spec have given us an amazing feature that helps to solve all of these problems: Grid Areas!


# Areas

A **grid area** is a rectangular section of a grid, bounded on each side by a grid line (so 4 grid lines, 2 horizontal and 2 vertical).

The simplest (and least interesting) way to use this feature is just as a shorthand for rows and columns on a grid item. Each of the sections in the example above could be simplified to a single `grid-area` rule:

```css
/*
 grid-area: row-start / col-start / row-end / col-end;
*/

.about {
  grid-area: 3 / 1 / 5 / 3;
}
```

But that doesn't really solve any of the problems I listed; in fact, you might argue that it's worse, because it's a bit harder to read. (Which number represents `grid-row-end` again?)

So instead of that, instead of all these tracks and lines, let me show you a CSS Grid feature that absolutely blew my mind when I saw it: [`grid-template-areas`](https://developer.mozilla.org/en-US/docs/Web/CSS/grid-template-areas)!

```css
main {
  display: grid;
  grid-template-areas: 
    "avatar avatar  name  name  name"
    "avatar avatar  posts posts posts"
    "about  about   posts posts posts"
    ".      .       posts posts posts"
  ;
}
.display-name {
  grid-area: name;
}
.avatar {
  grid-area: avatar;
}
.about {
  grid-area: about;
}
.posts {
  grid-area: posts;
}
```

{% codepen https://codepen.io/kenbellows/pen/REjyxW %}


Look at that.

Right?

*Right???*

Instead of defining rows and columns, we've laid out the whole grid *visually* with named grid areas, using what [Rachel Andrew](https://rachelandrew.co.uk/) calls the ["ASCII art"](https://gridbyexample.com/video/grid-template-areas/) method of describing a grid. Each row is written as a string surrounded with double quotes ("..."), and each cell is given the name of the grid area it belongs to. If a cell doesn't need to belong to any area, just put a dot (or several dots, stylistic preference) in that spot. Cells are whitespace-separated, and excess whitespace is collapsed, which makes formatting the grid visually very easy.

Each grid area is defined by all the cells that bear its name. As you might guess, your areas must be **rectangular** and **continuous**; no tetris blocks or wormholes here.

Once you've got your grid areas defined, you can attach your grid items to them by setting an item's `grid-area` rule to the name of the area where you want it to go!

Note that there's no `grid-template-columns` or `grid-template-rows` here; by default, tracks are just inferred from the ASCII art! (*How freaking cool is that??*) With that said, you can still use those rules if you want to; this is often still necessary for sizing. You can also use the shorthand [`grid-template`](https://developer.mozilla.org/en-US/docs/Web/CSS/grid-template) rule to define all three rules at once. In this shorthand, you can optionally give each row a height immediately following its description, then if you want column sizes you can add a slash after the final row and specify column sizes at the end:

```css
grid-template:
  "avatar avatar  name  name  name"   2rem
  "avatar avatar  posts posts posts"
  "about  about   posts posts posts"  6rem
  "...... ......  posts posts posts"
  / 2fr    10px    3fr   1fr   5vw
;
```

IMHO, this is orders of magnitude more readable, visualizable, and ultimately maintainable for grid layouts with static items than long lists of explicit grid lines.

# Responsiveness and Semantics

If I were asked what I think is the most exciting thing about CSS Grid, I would have to answer with this: the biggest benefit to the web that CSS Grid provides is that **responsiveness is easy to accomplish without sacrificing semantics.**

In the user profile example above, the careful reader may have noticed something odd: in the HTML, the order of the sections was:

* display name
* avatar
* about
* posts

But in the grid layout, the avatar came first, followed by the display name to the right, the about section below, and the posts in the bottom right. In addition, the posts section overlapped the avatar and the about section vertically.

The key point is this: the HTML tags are written in an order that makes sense *semantically*, but the grid layout makes sense *visually*. The HTML is written in the order that I would want a user to read the information. This is especially important for a user using assistive technology, like a screen reader: the fact that the CSS is moving things around on the page visually has no affect on the order of the elements, so the semantics is preserved.

That covers the semantics aspect, but what was that about responsiveness? Well, consider what would happen if the user were to narrow our profile layout to a mobile size, specifically a vertical orientation on a smaller screen. (Maybe you're already reading this on a mobile device, so you don't have to imagine!) It wouldn't look great. So let's add in a media query breakpoint at, say, `800px` to rearrange our layout to reflect the section order listed above. You ready for this? Here's the code:

```css
@media(max-width: 800px) {
  main {
    grid-template-areas:
        "name"
        "avatar"
        "about"
        "posts"
    ;
  }
}
```

*Boom.* That's it. That's all it takes.

It's just as visual as the first layout. And if you wanted a third layout, maybe one for super-wide screens that gets a little crazy and moves the avatar into a third column off to the left, that's just as easy:

```css
@media(min-width: 1500px) {
  main {
    grid-template-areas:
        "avatar name  posts"
        "avatar about posts"
        ".      .     posts"
    ;
  }
}
```

Here's a demo that includes all three layouts above, but uses the [`grid`](https://developer.mozilla.org/en-US/docs/Web/CSS/grid) shorthand rule, which resets values like track sizes. This avoids track sizes from the default layout being inherited in the other layouts, where they cause problems, without requiring me to override them explicitly in each breakpoint.

*Note: You can use the little "1x", "0.5x", and "0.25x" buttons under the codepen widget to see the three different layouts.*

{% codepen https://codepen.io/kenbellows/pen/zyPaar %}


And in all three layouts, the HTML source order is never changed, so a user reading with a screen-reader, or for that matter a web crawler or screen-scraper, would still get the information on the page in the preferred semantic order.


# Conclusion

I hope you're with me on this. I still hear pushback from web devs who have yet to seriously look into CSS Grid that they don't want to learn another new thing, that it's basically the same as the float- or Flexbox-based grid system they already know and use, or, most egregious of all, that it's just a return back to *table-based layouts*.

I hope I've shown in this article just how powerful CSS Grid is, both in terms of the layouts it can produce and in terms of just how *easy* it can be to create and maintain flexible, responsive, beautiful layouts, and all without sacrificing well-structured, slim, semantically pure HTML.

Once more I want to give huge props to Rachel Andrew. If you don't know her site [gridbyexample.com](https://gridbyexample.com), check it out. She has been personally advocating for CSS Grid for a decade, and she, along with [Jen Simmons](http://jensimmons.com), has basically taught me Grid through her videos and tutorials. I'll give Rachel the last word:

{% twitter 962723731104727040 %}