Getting Started with CSS Grid Layout ― Scotch

Introduction

CSS Grid Layout allows us to construct custom grids with more flexibility and control than ever before. Grid Layout gives us the ability to divide a webpage into rows and columns with simple properties. It also allows us to position and size each element inside the grid using CSS only, without any change to the HTML.

Defining a Grid

With this module, comes a new value for the display property: grid. When you set the display property of any element to grid, it becomes the grid container and all it’s child elements become grid items.

For the sake of creating a 3×3 layout, let’s create the board of a Tic-Tac-Toe game. First, we will write some HTML:

<div class="game-board">
  <div class="box"></div>
  <div class="box"></div>
  <div class="box"></div>
  <div class="box"></div>
  <div class="box"></div>
  <div class="box"></div>
  <div class="box"></div>
  <div class="box"></div>
  <div class="box"></div>
</div>

As you can see, the .game-board div is the grid container and .box divs are grid items. Now we will position them 3 in a row with Grid Layout.

.game-board
{
    display: grid;
    grid-template-rows: 200px 200px 200px;
    grid-template-columns: 200px 200px 200px;
}

Here, I’ve used two other properties as well. The grid-template-rows property allows us to specify how many rows and of what sizes there should be in the grid. I think you can guess what the other property does. The grid-template-columns property allows us to specify how many columns and of what sizes there should be in the grid. You can specify the size in any unit including pixels, percentages and another unit fr, which we are going to learn next.

The fr Unit

fr is a new unit defined for Grid Layout. It helps you get rid of calculating percentages and divides the space into a fraction of the available space. For example, if you place this rule:grid-template-rows: 2fr 3fr, in your grid element’s block, then your grid container will, firstly, be divided into 2 rows. Then the fractional parts will be added together which, here, sum up to 5. The first 2 parts of the available space will be allocated for the first row and the last 3 parts of the available space would be allocated for the second row.

Back to our Tic-Tac-Toe example, let’s use fr instead px. What we want is, that, there should be 3 rows and 3 columns. So, we just have to replace the 3 200px with 3 1fr like this:

.game-board
{
    display: grid;
    grid-template-rows: 1fr 1fr 1fr;
    grid-template-columns: 1fr 1fr 1fr;
}

The repeat() Function

In some cases, we have a lot of columns and rows. Specifying each one in the grid-template properties can get tedious. Luckily there is a repeat function which like any loop repeats a certain value a given number of times. It takes two arguments. First one is the number of iterations and second is the value to be repeated. Let’s rewrite our previous example using the repeat function.

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

There is a shorthand property for specifying both the grid-template-rows and grid-template-columns, that is the grid-template property. Here is it’s syntax:

grid-template: ro ws / co lu mns;

Using this shorthand, our previous example looks pretty neat.

.game-board
{
    display: grid;
    grid-template: repeat(3, 1fr) / repeat(3, 1fr);
}

See, just using 2 lines of code you can make a 3×3 grid with Grid Layout.

With some added paint and polish, the above example looks like this:

Grid Line Number, Cell & Tracks

A grid line is a line that exists on each side of a column and a row. One set of lines divide the space vertically into columns and the other set of lines divide the space horizontally into rows. This means that in our previous example, there were four vertical lines and four horizontal lines containing the rows and columns between them.

Grid Lines in a Tic-Tac-Toe Boards

Grid Lines become quite useful while moving grid items from one place to another in the grid.

A grid track is the space between two lines. A grid track can either be a row or a column.

A grid cell, much like a table cell, is the space between two vertical lines and two horizontal lines. It is the smallest unit of the grid.

Positioning Grid Items

I’ve taken the grid of the previous example and labeled each cell, not with a X or O, but with a number from 1 to 9. Here’s how it looks:

Numbered Grid

Let’s say I want to move the sixth box to the place of the second box. Without CSS Grids, this would have been an almost impossible task, at least for me, without changing the HTML. But with this new module, changing position of items in a grid is a breeze. To move the sixth box to the place of the second box, we must know exactly where the second box is sitting. And we can easily find this with the help of grid line numbers. The second box is sitting after line 2 and before line 3 on the vertical axis and after line 1 and before line 2 on the horizontal axis. Now we can assign these grid line numbers to the sixth box using the following properties:

  • grid-column-start
  • grid-column-end
  • grid-row-start
  • grid-row-end

The first two properties correspond to the vertical lines’ start and end. And the last two properties refer to the horizontal lines’ start and end. Let’s assign the correct line numbers to move the sixth box.

.box:nth-child(6)
{
    grid-row-start: 1;
    grid-row-end: 2;
    grid-column-start: 2;
    grid-column-end: 3;
}

There are also two shorthand properties for setting the start and end lines of row and column in one line.

.box:nth-child(6)
{
    grid-row: 1 / 2;
    grid-column: 2 / 3;
}

Additionally, there is a grid-area property which is the shorthand property of all four above mentioned properties. It takes values in the following order:

grid-area: <row-start> / <column-start> / <row-end> / <column-end>;

Now, our example looks like this:

.box:nth-child(6)
{
    grid-area: 1 / 2 / 2 / 3;
}

The above line of code can also be further reduced. As you can see that the box only takes up one row and one column, so we only need to specify the starting lines of the row and column and not the end values.

.box:nth-child(6)
{
    grid-area: 1 / 2;
}

What if we wanted the sixth box to span the area of two boxes? This can easily be done by increasing the column-end value by 1.

.box:nth-child(6)
{
    grid-area: 1 / 2 / 2 / 4;
}

Double Column Span

You can also use the span keyword with the number of tracks instead of specifying the ending line number for grid-row-end and grid-column-end. In this case, the sixth box is spanning 2 columns and 1 row.

.box:nth-child(6)
{
    grid-area: 1 / 2 / 2 / span 2;
}

Named Grid Areas

The grid-area property can also be used to name parts of a grid which we can then position with the grid-template-areas property. Let’s create a simple bread-and-butter layout with a header on top, nav, main and aside in the middle, and a footer below them. Here’s the HTML required for this:

<div class="container">
  <header></header>
  <nav></nav>
  <main></main>
  <aside></aside>
  <footer></footer>
</div>

We need to name each area using the grid-area property like this:

header
{
  grid-area: header;
  background-color: #9b59b6;
}

nav
{
  grid-area: nav;
  background-color: #3498db;
}

main
{
  grid-area: main;
  background-color: #2ecc71;
}

aside
{
  grid-area: aside;
  background-color: #f1c40f;
}

footer
{
  grid-area: footer;
  background-color: #1abc9c;
}

Now we will use the grid-template-areas property to specify which rows and columns each grid area has to span across. Here’s how we do it:

.container
{
      display: grid;
      grid-template-rows: 1fr 5fr 1fr;
      grid-template-columns: 2fr 5fr 3fr;
      grid-template-areas:
        "header  header  header"
        "nav     main    aside"
        "footer  footer  footer";
      grid-gap: .75em;
}

Notice that the header and footer words are repeated three times. This states that both the header and the footer span across the width of 3 rows. You can write all of it in one line but it’s nice and clean to write each row on a separate line. You can see that I’ve used a new property grid-gap here. All it does is simply add a gutter between two grid areas. You can also specify different gutter values for row and column using grid-row-gap and grid-column-gap.

Here’s the CodePen for this example:

Browser Support

At the time of this writing, there is good browser support for CSS Grid Layout. According to caniuse.com, all major browsers support CSS Grid Layout except Internet Explorer 11 which has partial support with -ms- prefix and Opera Mini having no support at all.

Conclusion

CSS Grid Layout allows us to make layouts faster and with more control and ease. In this tutorial, we learned how to define layouts with CSS Grids, the fr unit, the repeat function and some grid-specific glossary. We also learned how to position grid items inside a grid container using grid-lines and grid-named-areas. But that’s just the start. In the next tutorial, we will dive deep into CSS Grids.

Til then, Happy Coding!