May 23, 2023

A Beginner’s Guide to Mastering CSS Grid

When you are developing a website, creating the exact page layout and item placement you want with CSS is a bit of a tricky task. Sometimes there’s no straightforward way to tell CSS where to place items without using a roundabout and drawn-out hacks that involve properties like float, table, inline-block, etc. 

CSS flexbox provides a little relief to developers in this department but, being the largely one-dimensional system it is, flexbox is not a complete solution. 

But CSS has a better solution to impose a layout you want on a web page: CSS Grid. It allows the creation of a basic layout on which you can place web elements to give them a precise placement. Since the introduction of the grid layout a few years ago, frontend developers have relied heavily on it to give their websites a better and cleaner look. 

In this tutorial, we are going to walk you through everything you need to know on the CSS grid to create amazing page layouts with it in your next web development project. 

Why wait any longer, then? Let’s begin. 

What is the CSS Grid Layout?

It is a two-dimensional grid system made up of intersecting horizontal and vertical lines. You can use the columns and rows it forms to specify the exact place different elements should be placed on. With the grid system, you can easily define a layout for both smaller and larger areas on the web interface. Grid layouts support responsive design too. 

An example grid layout

If you only look at this picture, you won’t be able to say it apart from a regular table. But you’ll understand that a grid is not even comparable to a table as we go along. The closest thing to the grid you can find in CSS is flexbox. 

But CSS grid is different from flexbox primarily because of its two-dimensional layout. Whereas an item positioned inside a flexbox depends on the content inside it, the grid first defines the layout and gives you the control of placing elements in specific positions on that layout. 

Browser support for CSS Grid

Since the CSS grid was introduced a few years ago, it’s now supported by almost all major browsers as of 2021. The partial support in Internet Explorer and Opera Mini are the only noticeable exceptions. 

Let’s create a simple grid

Before we dig deeper into the theoretical side of the grid, let’s see how we can create a simple grid layout in CSS. 

First, we need to add the basic HTML structure that is used to build the layout. We can create this using a few divs. 


<div class="grid-container">
  <div class="grid-item"></div>
  <div class="grid-item"></div>
  <div class="grid-item"></div>  
  <div class="grid-item"></div>
  <div class="grid-item"></div>
  <div class="grid-item"></div>  
  <div class="grid-item"></div>
  <div class="grid-item"></div>
  <div class="grid-item"></div>  
</div>


Next, we use CSS to create the grid layout.

.grid-container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  padding: 10px;
  gap: 5px;
  grid-auto-rows: minmax(70px, auto);
  background-color: #e37d39;
}
.grid-item {
  background-color: rgba(0, 0, 0, 0.6);
  border: 1px solid rgba(0, 0, 0, 0.8);
  padding: 20px;
  color: #ffffff;
}

You can see the resulting grid layout in the following image.

The properties specific to the grid layout we’ve used here might be new to you. We’ll get back to them in a minute. Before that, however, I want to introduce you to a few words commonly used when talking about the grid system. 

Commonly used words with CSS Grid

These words are used to refer to different positions and elements in a grid. Let’s see what they are. 

Grid container

The grid container is the parent element that holds the entire grid. In the above example, the “grid-container” was the container of the grid we created. To declare an element as the grid container, you need to set the display: grid property in CSS. 

<div class="grid-container">
  <div class="grid-item"></div>
  <div class="grid-item"></div>
</div>
.grid-container {
  display: grid;
 }

Grid item

All the direct descendants of the container element are grid items. In the following example, elements that belong to the “grid-item” class are grid items. A child element of a grid item, however, is not a grid item.

Grid line

Grid lines are either horizontal or vertical lines that make up the basic structure of the grid by dividing the area into separate blocks. They can be called either row grid lines or column grid lines depending on them being horizontal and vertical lines respectively.

Grid cell

A grid cell is an area surrounded by two adjacent row and column grid lines. It’s the smallest unit on a grid. 

Grid track

Grid track is the area in between two adjacent vertical or horizontal grid lines. 

Grid area

Grid area is any area surrounded by four grid lines. There can be any number of grid cells inside a grid area. 

Basic grid properties

In the previous simple grid we created, you can see some properties that are unique to the grid system. grid-template-columns and grid-auto-rows are two such examples. In this section, we’ll talk about the grid properties that would be useful to you when creating a grid layout. 

First, we’ll start with properties used in the grid container.

Grid container properties

display

This is used to define an element as the grid container. The value can be either grid or inline-grid

grid-template-columns / grid-template-rows

You can use these two properties to set the number and size of columns and rows in the grid. It accepts a list of space-separated values to use as the size of each column. The value can be a length in pixel, a percentage, or a fraction (using fr unit). 

.grid-container {
  grid-template-columns: 100px 25% auto;
  grid-template-rows: 60px 70px auto;
}

If the column and row sizes have repeated values, instead of passing each value to the property, you can use the repeat notation. 

.grid-container {
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 1fr);
}

grid-template-areas

This property allows you to create a grid template by using grid-areas. To reference a grid area in the template, first, you should specify the name of the grid area using the grid-area property. 

<div class="grid-container">
  <div class="grid-item a"></div>
  <div class="grid-item b"></div>
  <div class="grid-item c"></div> 
  <div class="grid-item d"></div> 
</div>
.a {
  grid-area: main;
}
.b {
  grid-area: header;
}
.c {
  grid-area: footer;
}
.d {
  grid-area: sidebar;
}
.grid-container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap:5px;
  grid-auto-rows: minmax(70px, auto);
  background-color: #e37d39;
  grid-template-areas:
    "header header header"
    "main main sidebar"
    "main main sidebar"
    "main main ."
    "footer footer footer"
}

Here, the dot indicates an empty space in the layout. The resulting layout of the template is this. 

gap

The gap property is used to set a gap between rows and columns in the grid. 

.grid-container{
  display: grid;
  gap: 2px 10px;
}

CSS also provides two properties to set gaps between rows or columns individually. They are grid-row-gap and grid-column-gap

.grid-container{
    display: grid;
    grid-row-gap: 10px;
    grid-column-gap: 3px;
}

justify-items 

This property is used to align all the grid items along the horizontal axis. You can align them to the start, center, end, or stretch them to fill up the whole width of the cell (it’s the default value). 

.grid-container{
  justify-items: start;
}
.grid-container{
  justify-items: center;
}
.grid-container{
  justify-items: end;
}

align-items

align-items is used to align the grid items along the vertical axis. Here too you have the option to align them to the start, center, end, or stretch (default).

.grid-container{
  align-items: start;
}
.grid-container{
  align-items: center;
}
.grid-container{
  align-items: end;
}

place-items 

This property sets align-items and justify-items properties in a single assignment. 

.grid-container{
  place-items: end center;
}

justify-content

This property controls the alignment of the entire grid inside the container along the horizontal axis. 

.grid-container{
  justify-content: start;
}
.grid-container{
  justify-content: center;
}
.grid-container{
  justify-content: end;
}

align-content

This property aligns the entire grid along the vertical axis of the container. 

.grid-container{
  align-content: start;
}
.grid-container{
  align-content: start;
}
.grid-container{
  align-content: center;
}
.grid-container{
  align-content: end;
}

place-content

place-content sets both justify-content and align-content in a single assignment. 

grid-auto-columns / grid-auto-rows 

These two properties are used to specify the size of auto-generated grid tracks. Grid tracks are automatically created when there are more grid items than cells in the grid or when a grid item is placed outside the explicitly declared grid. 

In the first grid we created, we used this grid-auto-rows property to define the height of a grid item. 

.grid-container {
  grid-template-columns: repeat(3, 1fr);
  grid-auto-rows: minmax(70px, auto);
}

You can either use the minmax notation to declare the size of the auto-generated tracks—like we have done here—or directly pass the size to the property. 

grid-auto-rows: 70px;

grid-auto-flow

If there are grid items that aren’t explicitly placed on the grid, CSS uses an auto-placement algorithm to decide the best place to put them. You can use the grid-auto-flow algorithm to control the priorities of the auto-placement algorithm. 

The values accepted by this property are row (default), column, and dense. When the value row is passed, the auto-placement algorithm fills the rows of the grid with items that aren’t explicitly placed. If necessary, it adds new rows to accommodate all the items. Similarly, when the value column is passed, the algorithm fills columns in the grid. Dense tells the algorithm to fill the holes in the grid if smaller items come up later. 

grid 

This property is a shorthand way of setting the following properties of the grid container in a single declaration. 

  • grid-template-rows
  • grid-template-columns
  • grid-template-areas
  • grid-auto-rows
  • grid-auto-columns
  • grid-auto-flow
.grid-container {
  display: grid;
  gap: 2px;
  grid: repeat(2, 70px) /auto-flow 1fr;
}

This grid assignment is equivalent to the use of the following separate properties. 

.grid-container {
  display: grid;
  gap: 2px;
  grid-template-rows: repeat(2, 70px);
  grid-auto-columns: 1fr;
  grid-auto-flow: column;
}

Grid item properties

grid-column-start / grid-column-end / grid-row-start / grid-row-end

These properties are used to specify the placement of a grid item in the grid in relation to specific grid lines. The gridlines used are the start and end grid lines of a row or a column.

When specifying the location, you can pass the number of the grid line or the number of grid lines the item spans across. 


.grid-item-a {
    grid-column-start: 1;
    grid-column-end: span 2;
    grid-row-start: 1;
    grid-row-end: 4;
}


If grid-column-end or grid-row-end is not specified, the grid item will span only one cell by default. 

Using these properties, you can control item placement in a way that they overlap each other. Then, use z-index to control the order they are stacked. 


.grid-item-a {
    grid-column-start: 1;
    grid-column-end: span 2;
    grid-row-start: 1;
    grid-row-end: 4;
    z-index: 1;
}
.grid-item-b {
    grid-column-start: 2;
    grid-column-end: span 2;
    grid-row-start: 2;
    grid-row-end: 5;
    z-index: 3;
}
.grid-item-c {
    grid-column-start: 3;
    grid-row-start: 1;
    grid-row-end: span 5;
    z-index: 2;
}


grid-column / grid-row

grid-column is used to declare grid-column-start and grid-column-end in a single assignment. grid-row is used to declare grid-row-start and grid-row-end in a single assignment. 

Here, you assign the start and end grid line numbers separated by a “/” symbol.

.grid-item-a {
    background-color: rgba(0, 0, 0, 1);
    grid-column: 1 / 3;
    grid-row: 2 / 4
}

grid-area

We came across the grid-area property when we were discussing the grid-template-areas property of the grid container. We used it to provide a name to an area in the grid. 

.grid-item-a {
  grid-area: header;
}

We can also specify the space covered by this area using grid line numbers. In this case, grid-area property acts as a single assignment of grid-column-start, grid-row-start, grid-column-end, and grid-row-end in that order. 

.grid-item-a {
  grid-area: 1 / 2 / 3 / 4;
}

justify-self 

This property is used to align a grid-item along the horizontal axis of the cell it is located in. The resulting behavior is similar to what we saw in the justify-items property of the grid container but affects one grid item instead of all. 

The property value can be one of start, end, center, and stretch (default).

.grid-item-a {
  justify-self: center;
}

align-self 

This property is used to align a grid item along the vertical axis of the cell it is located in. The resulting behavior is similar to what we saw in the align-items property of the grid container but affects one grid item instead of all. 

Similar to justify-self, it accepts values start, end, center, and stretch;

.grid-item-a {
  align-self: end;
}

place-self

place-self property is used to assign justify-self and align-self values in a single declaration. 

.grid-item-a {
  place-self: center end;
}

Summary

As you may have seen after going through this tutorial, the CSS grid provides us a simplified way to create layouts when designing a web page. Using the properties you learned today, you can create smooth and elegant web designs we see in modern web development without relying on hacks to place your elements exactly where they should go.

The next step of mastering the CSS grid is experimenting with it to create increasingly advanced layouts. What we discussed in this tutorial will be more than enough to set you off on that path. So, go on and build things with CSS Grid. I promise it will be fun!