Construct layout with grid template areas

Khai Bui,CSSFront-end

Since CSS Grid was supported by almost major browsers (like Chrome, Safari, Opera, etc) in 2017. That opened an amazing way to build any type of layout commonly.

I never used it for my client project until I had a look at some articles. In 2023, might make sure this is the best simple way to construct complex layouts in web development. We can find the browser compatibility:

Browser compatibility MDN

Some regular ways to add layout

Consider the following design mockup layout:

Basic layout sample

With flex-box solution

Before the introduction of the grid technique. Usually, I set flex-box for each element header, sidebar, main, and footer like below:

HTML
<div class="container">
  <header></header>
  <div class="box">
    <aside></aside>
    <main></main>
  </div>
  <footer></footer>
</div>
CSS
.container {
  height: 100vh;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}
 
.box {
  flex-grow: 1;
  display: flex;
  gap: 0.5rem;
}
 
header {
  height: 50px;
  width: 100%;
}
 
aside {
  flex-basis: 100px;
}
 
main {
  flex-grow: 1;
}
 
footer {
  height: 50px;
  width: 100%;
}

This is a good alternative solution without grid technique. It looks good whether the layout does not contain complex scrollable components. In the worst case, the overflow inside the main and aside components will conflict with each other. Otherwise, using wrapping for aside and main will have limitations with responsive actions and a flexible layout.

With grid solution

Another modern way to implement a layout is using grid:

HTML
<div class="container">
  <header></header>
  <aside></aside>
  <main></main>
  <footer></footer>
</div>
CSS
.container {
  display: grid;
  grid-template-columns: 100px 1fr;
  grid-template-rows: 50px 1fr 50px;
  grid-gap: 0.5rem;
  min-height: 100vh;
}
 
header {
  grid-column: 1 / 3;
}
 
footer {
  grid-column: 1 / 3;
}

By grid solution, we could prevent unnecessary wrapping elements with a little bit of CSS code. On the other hand, responsive actions will become easier because of pure elements. This works perfectly if the structure of the website or the layout you are working on will never change. However, this is not quite possible on the web. The web is fluid and thus the layouts we build should be like so.

More complex when the layout changed

For instance, we changed our minds and decided to make the sidebar span to the end of the page, and the footer should have the same width as the main element. To do that, we need to change the value of grid-column for the main, aside, and footer elements.

More complex layout sample

The CSS comes:

CSS
.container {
  display: grid;
  grid-template-columns: 100px 1fr;
  grid-template-rows: 50px 1fr 50px;
  grid-gap: 0.5rem;
  min-height: 100vh;
}
 
header {
  grid-column: 1 / 3;
}
 
aside {
  grid-row: 2 / 4;
}
 
footer {
  grid-column: 2 / 3;
}

I still find it hard to change or remember the number of columns and rows for each layout edit. Maybe there is a better visual way for that without getting caught in numbers every time an edit is needed?

Introducing Grid Template Areas

Instead of dealing with columns and rows numbers, there is a better way by using grid-template-areas. Simply, it makes a visual representation of the grid columns and rows.

grid-template-areas: none | <string> +;

Each child element in the grid will be named by text. That is presented as the value of grid-template-areas . This is a strong solution and easy to understand for everyone can build a stable layout with less markup code. Now, we will redo the example above to understand how it works.

CSS
.container {
  display: grid;
  grid-template-columns: 100px 1fr;
  grid-template-rows: 50px 1fr 50px;
  grid-gap: 0.5rem;
  min-height: 100vh;
  grid-template-areas:
    'header header'
    'aside main'
    'aside footer';
}
 
/* Naming area by grid-area */
 
header {
  grid-area: header;
}
 
aside {
  grid-area: aside;
}
 
main {
  grid-area: main;
}
 
footer {
  grid-area: footer;
}

The grid-template CSS property is a shorthand property for defining grid columns, grid rows, and grid areas. So, .container class can be rewritten for clarify:

grid-template:
  'header header' 50px
  'aside main' 1fr
  'aside footer' 50px
  / 100px 1fr;

To understand the grid-template-areas value, see the below illustration about it.

Describe grid areas by illustration

Empty areas layout

Sometimes, a hidden area is required. The grid-template-areas ready support by easy method to implement:

.container {
  display: grid;
  grid-gap: 0.5rem;
  min-height: 100vh;
  grid-template:
    '. header' 50px
    'aside main' 1fr
    'aside footer' 50px
    / 100px 1fr;
}

The dot placed means that this cell is empty and the head should be placed on the second column. The result is as below:

Empty some part

Use cases and examples

Responsive layout

CSS Grid is a powerful grid-based layout system in Cascading Style Sheets that makes it simple to design complex responsive web layouts across browsers using a two-dimensional grid.

grid-template-areas provide a visualization method. That made developers become so quick to construct complex responsive layouts for many device sizing.

Stack responsive design

By CSS grid, we spend less time implementing many screen responsive with less code:0.5rem

HTML
<div class="container">
  <div class="item-01"></div>
  <div class="item-02"></div>
  <div class="item-03"></div>
</div>
CSS
/* Stacked */
.container {
  display: grid;
  grid-gap: 0.5rem;
  min-height: 100vh;
  grid-template-columns: 1fr 1fr 1fr;
  grid-template-areas:
    'item-01 item-01 item-01'
    'item-02 item-02 item-02'
    'item-03 item-03 item-03';
}
 
/* 3-col */
@media (min-width: 600px) {
  .container {
    grid-template-areas: 'item-01 item-02 item-03';
  }
}
 
/* Featured */
@media (min-width: 800px) {
  .container {
    grid-template-areas:
      'item-01 item-02 item-02'
      'item-01 item-03 item-03';
  }
}
 
.item-01 {
  grid-area: item-01;
}
 
.item-02 {
  grid-area: item-02;
}
 
.item-03 {
  grid-area: item-03;
}

Media element

The media component is a good use case for grid areas. Let’s say that we want to switch the placement of the media and the content. Grid area is perfect for that.

Media flip cards

HTML
<div class="container">
  <article class="item">
    <div class="image"></div>
    <div class="content"></div>
  </article>
  <article class="item">
    <div class="image"></div>
    <div class="content"></div>
  </article>
</div>
CSS
.list {
  display: flex;
  flex-direction: column;
}
 
.item {
  display: grid;
}
 
.item:nth-child(odd) {
  grid-template-areas: 'image content';
}
 
.item:nth-child(even) {
  grid-template-areas: 'content image';
}
 
.image {
  grid-area: image;
}
 
.content {
  grid-area: content;
}

Conclusion

Summary, Using grid-template-areas, I have a new method for creating your layout that is both quicker and more obvious. In future projects, you can find more examples and applications. Gratitude for reading!

Reference resources

Read grid-template-areas article in CSS-tricks

Document grid-template-areas in MDN

© Bùi Quốc Khải.