CSS Grid: One Layout, Multiple Ways

Avatar of Geoff Graham
Geoff Graham on (Updated on )

I’ve really been enjoying getting acquainted with CSS Grid. The feature is starting to ship in many browsers and it looks like we’ll be able to start using it in production in due time.

One of the things that stands out most to me about CSS Grid is the fact that the syntax is so flexible. To demonstrate this point, we’re going to look at how we can create the same layout in three different ways, all using CSS Grid properties. In particular, we’re going to use the Holy Grail layout as our example:

The Holy Grail Layout

To get started, we’re going to define a parent element called, creatively, .grid and set up three columns and three rows set the stage for our different layout methods:

.grid {
  display: grid;
  grid-template-columns: 150px auto 150px;
  grid-template-rows: repeat(3, 100px);
  grid-gap: 1em;
}

This says that our .grid element has three columns (two set to 150px and one that flexibly occupies the remaining space) and three row (all set to 100px for demonstration purposes).

We will also be playing with the following child elements in each example: <header>, <footer> .sidebar-left, sidebar-right and <article>. These will be the building blocks for our layout and will be represented in the HTML as follows:

<div class="grid">
  <header>
    Header
  </header>

  <aside class="sidebar-left">
    Left Sidebar
  </aside>

  <article>
    Article
  </article>

  <aside class="sidebar-right">
    Right Sidebar
  </aside>
  
  <footer>
    Footer
  </footer>
</div>

Alright, let’s re-create this in three ways using CSS Grid!

Method 1: Specifying Grid Columns

We can define which cells of the grid each child element occupies directly on the elements themselves:

header {
  /* Start on Row 1 */
  grid-row: 1;
  /* Start on the first column line and extend all the to the last column line */
  grid-column: 1 / 4;
}

.sidebar-left {
  /* Start on Row 2 */
  grid-row: 2;
  /* Start on the first column line and stop at the next column line */
  grid-column: 1 / 2;
}

article {
  /* Start on Row 2 */
  grid-row: 2;
  /* Start on the second column line and stop at the third column line */
  grid-column: 2 / 3;
}

.sidebar-right {
  /* Start on Row 2 */
  grid-row: 2;
  /* Start on the third column line and stop at the last column line */
  grid-column: 3 / 4;
}

footer {
  /* Start on Row 3, the last row */
  grid-row: 3;
  /* Start on the first column line and extend all the to the last column line */
  grid-column: 1 / 4;
}

See the Pen CSS Grid – Holy Grail 1 by Geoff Graham (@geoffgraham) on CodePen.

That gives us everything we need to create the layout! We can do better, though, so let’s move right along.

Method 2: Condense the Markup from the First Method

CSS Grid is smart enough to calculate where our sidebars and article go if all we do is specify where the <header> and <footer> go:

header, footer {
  grid-column: 1 / 4;
}

That’s it! since we’ve identified that both the <header> and <footer> should take up the full width of the .grid element, CSS Grid will flow the rest of the elements into their place without us having to tell it anything else. Nice!

See the Pen CSS Grid – Holy Grail 2 by Geoff Graham (@geoffgraham) on CodePen.

Method 3: Defining Grid Template Areas

CSS Grid also allows us to name our elements using the grid-area property and place them on the parent element using the grid-template-areas property.

Let’s name our child elements using grid-area:

header {
  grid-area: header;
}

footer {
  grid-area: footer;
}

.sidebar-left {
  grid-area: sidebar-1;
}

article {
  grid-area: article;
}

.sidebar-right {
  grid-area: sidebar-2;
}

Now, let’s name those areas on the parent .grid element using grid-template-areas:

.grid {
  display: grid;
  grid-template-columns: 150px auto 150px;
  grid-template-rows: repeat(3, 100px);
  grid-gap: 1em;
  grid-template-areas: "header header header"
                       "sidebar-1 article sidebar-2"
                       "footer footer footer";
}

See how we can create the layout by adding the named areas on the property? That’s almost like having a visual editor right in our code!

See the Pen CSS Grid – Holy Grail 3 by Geoff Graham (@geoffgraham) on CodePen.

Wrapping Up

We could definitely go much deeper into the greatness that is CSS Grid, but I wanted to dig specifically into how flexible the syntax is when it comes to creating layouts, particularly one that used to be such a pain to create in the days of floats.

Are there other ways we could achieve the Holy Grail layout using CSS Grid that we haven’t covered here? Submit a comment and let us know and we’d be happy to add it in.