How to setup a layout with CSS Grid
Published: 2023-03-11 19:24:00

---
title: How to setup a layout with CSS Grid
published: true
description: How to setup a web layout with CSS Grid. Discussing CSS media queries, CSS Grid template areas
tags: 
cover_image: https://blog-files-prod.s3.us-east-2.amazonaws.com/public/how-to-setup-a-layout-with-css-grid/how-to-setup-a-layout-with-css-grid.jpg
# Use a ratio of 100:42 for best results.
published_at: 2023-03-11 19:24 +0000
---

Table of Contents

1. [Introduction](#introduction)
2. [How to create a CSS Grid container](#how-to-create-a-css-grid-container)
3. [How to use CSS Grid template areas](#how-to-use-css-grid-template-areas)
4. [How to use CSS media queries with CSS Grid template areas](#how-to-use-css-media-queries-with-css-grid-template-areas)
5. [Conclusion](#conclusion)

## Introduction

In this blog post, we are going to explain how to setup a simple, responsive web layout with CSS Grid and minimal layout CSS.

The topics we are going over include how to create a CSS Grid container, how to use CSS Grid template areas, and how to use CSS media queries with CSS Grid template areas - for building the responsiveness we are looking for, both simply and declaratively. [This](https://codepen.io/stephenc224/pen/yLRvNEV) is the [CodePen](https://codepen.io/) with the finished code we are going to be building in this tutorial blog post. Here's what it will look like:

<img src="https://blog-files-prod.s3.us-east-2.amazonaws.com/public/how-to-setup-a-layout-with-css-grid/grid-layout-image.png" alt="Basic CSS Grid layout image" style="height:unset;">

and on smaller screens:

<img src="https://blog-files-prod.s3.us-east-2.amazonaws.com/public/how-to-setup-a-layout-with-css-grid/grid-layout-image-mobile.png" alt="Basic CSS Grid layout image on mobile" style="height:unset">

## How to create a CSS Grid container

First up, we need to create a CSS Grid container. This is pretty easy to do, just set the display property of a CSS selector (like CSS classes) on our root element of our layout, like so:

```css
.home-content {
  display: grid;
}
```

At this point, and to expand our our layout to fill the parent (in this case, the body of the HTML5 document), our `home-content` class (our root layout CSS class) and our `body` CSS selector should look like this:

```css
body {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
  height: 100vh;
  width: 100vw;
}

.home-content {
  display: grid;
  width: inherit;
  height: inherit;
}
```

The HTML we are working with for this tutorial is entirely just this:

```html
<div class="home-content">
  <div class="line-1"></div>
  <div class="bar-0"></div>
  <div class="line-0"></div>
</div>
```

Pro tip: the `body` element is the root element of the content of the document (not discussing the `head` element here), so if we set it to have 0 margin and 0 padding (margin is _outside_ of an element's border, padding is _inside_ an element's border by the way), with box-sizing (for good practice) set to `border-box`, we can set the body to have a width of `100vw` and a height to `100vh` and we will completely, perfectly fill the viewport without any awkward scroll. And, if we set the `home-content` class to `inherit` the width and height of it's parent, our root layout element will completely fill the viewport (the "stuff" you see in the browser outside of the browser's UI).

With our root layout element CSS set, we can move on to how we can describe our layout with CSS Grid template areas.

## How to use CSS Grid template areas

First, we'll share the code, then break it down:

```css
.bar-0 {
  grid-area: bar-0;
  background: green;
  /* just so this grid child doesn't shrink too much*/
  min-width: 400px;
}

.line-0 {
  grid-area: line-0;
  background: orange;
}

.line-1 {
  grid-area: line-1;
  background: skyblue;
}

.home-content {
  display: grid;
  width: inherit;
  height: inherit;
  grid-template-columns: 3fr 1fr;
  grid-template-rows: repeat(10, 1fr);
  grid-template-areas:
    "line-0 bar-0"
    "line-0 bar-0"
    "line-0 bar-0"
    "line-0 bar-0"
    "line-0 bar-0"
    "line-1 bar-0"
    "line-1 bar-0"
    "line-1 ."
    "line-1 ."
    "line-1 .";
}

/* added for minimal polish of this codepen. Not important for the layout itself */
.home-content > div {
  margin: 0.5em;
  border-radius: 8px;
}
```

Let's explain what we are doing with the `line-0`, `line-1`, and `bar-0` CSS classes. The CSS Grid-related property we've added is called [grid-area](https://developer.mozilla.org/en-US/docs/Web/CSS/grid-area). What we are doing specifically here with `grid-area` is to name the particular CSS class as a CSS Grid area to let us then reference (for responsive positioning) in our parent grid (the `home-content` class). We can accomplish this referencing through the use of the [grid-template-areas](https://developer.mozilla.org/en-US/docs/Web/CSS/grid-template-areas) CSS grid property in our `home-content` CSS class.

The `grid-template-areas` property is what let's us "declaratively" describe what we want our layout to look like. Before we can get our CSS Grid to layout as we intend, we have to tell CSS Grid how to create the columns and rows of our grid. We can use [grid-template-columns](https://developer.mozilla.org/en-US/docs/Web/CSS/grid-template-columns) to create our grid's columns, and [grid-template-rows](https://developer.mozilla.org/en-US/docs/Web/CSS/grid-template-rows) to create our grid's rows, using generally either exact pixel units or a newer, more flexible unit called "fr", which [represents a fraction of the leftover space in the grid container](https://www.w3.org/TR/css3-grid-layout/#fr-unit). So, in our `home-content` class below:

```css
.home-content {
  display: grid;
  /* ... */
  grid-template-columns: 3fr 1fr;
  grid-template-rows: repeat(10, 1fr);
  /* ... */
}
```

What we are saying for our columns with the `grid-template-columns` property, is that we want our first column (the `3fr` number) to be three times larger than our second column (the `1fr` number), and we want both columns to expand to the full width of our grid container ("proportionally" expand on a 3-to-1 basis).

For our rows with the `grid-template-rows`, we state that we want ten rows each exactly equal to `1fr`. The [repeat](https://developer.mozilla.org/en-US/docs/Web/CSS/repeat) function is a nice convenience over typing out `1fr` ten times manually. The reason we are using a high number of rows here is to create the layout that's impossible with Flexbox without special, specific child class CSS or creating additional elements: in a single CSS Grid property, we can create an "uneven" yet responsive element (our `bar-0` div). Our `bar-0` grid area "overlaps" an imaginary horizontal cross-section between the `line-0` and `line-1` divs. We can now define our entire grid layout with the `grid-template-areas` CSS property like below:

```css
.home-content {
  display: grid;
  width: inherit;
  height: inherit;
  grid-template-columns: 3fr 1fr;
  grid-template-rows: repeat(10, 1fr);
  grid-template-areas:
    "line-0 bar-0"
    "line-0 bar-0"
    "line-0 bar-0"
    "line-0 bar-0"
    "line-0 bar-0"
    "line-1 bar-0"
    "line-1 bar-0"
    "line-1 ."
    "line-1 ."
    "line-1 .";
}
```

As an aside, something to mention here about the dot, "`.`" inside our `grid-template-areas` property. In order for our `grid-template-areas` to match up according to our `grid-template-rows` and `grid-template-columns` specifications, we need to have exactly 2 rows of 10 columns fully defined, but we want the bar-0 to "exactly overhang" by "3" `fr` units. So we use the dot, "`.`" to designate "hard stops" between cells. The net effect is to keep our grid sized as expected as well as for CSS Grid to know how to "responsively" handle the empty space of the last three cells at the bottom right of our grid. Try removing the dots on the [CodePen](https://codepen.io/stephenc224/pen/yLRvNEV); you'll see that the layout breaks.

This layout above looks pretty good on larger screens, but what about smaller screens, where multiple columns of content generally look bad? That's where we can use CSS media queries with CSS Grid.

## How to use CSS media queries with CSS Grid template areas

The general best practice for building responsive layouts is to define your smallest layout first (for the smallest screen sizes you will support), then use CSS media queries to re-define your major layout-controlling containers to (typically) expand to fill the additional space offered by larger screens. This often means things like allowing content to take up space horizontally, as well as vertically, rather than focusing on a vertically-oriented content for smaller screens like mobile phones.

So, for our grid-based layout, all we are going to do is define our smallest layout outside of any CSS media query first, and then define our multi-column layout for larger screens inside a single CSS media query (with a minimum screen width just set to `900px`):

```css
/* vertical-oriented layout suitable for smaller screens */
.home-content {
  display: grid;
  width: inherit;
  height: inherit;
  grid-template-columns: 1fr;
  grid-template-rows: repeat(3, 1fr);
  grid-template-areas:
    "line-0"
    "line-1"
    "bar-0";
}

/* taking advantage of larger screen real estate to add another column */
@media screen and (min-width: 900px) {
  .home-content {
    display: grid;
    width: inherit;
    height: inherit;
    grid-template-columns: 3fr 1fr;
    grid-template-rows: repeat(10, 1fr);
    grid-template-areas:
      "line-0 bar-0"
      "line-0 bar-0"
      "line-0 bar-0"
      "line-0 bar-0"
      "line-0 bar-0"
      "line-1 bar-0"
      "line-1 bar-0"
      "line-1 ."
      "line-1 ."
      "line-1 .";
  }
}
```

This works because of [how cascading works in CSS](https://developer.mozilla.org/en-US/docs/Web/CSS/Cascade). In our CSS, once the user's screen is at least `900px` wide, our CSS media query will become "activated" and since the `home-content` rule inside the CSS media query, defined _after_ our mobile layout `home-content` CSS class definition, the later CSS class definition (in our media query) will take precedence and override our mobile-oriented layout for targeting larger screens.

## Conclusion

In this blog post we've explained how to setup a simple web layout with CSS Grid using grid template areas. The complete layout can be found in the [CodePen](https://codepen.io/stephenc224/pen/yLRvNEV) we made for this blog post. Hope you found it helpful! Feel free to share and connect with me on [Twitter](https://twitter.com/stephenc1webdev).