I just learned about CSS grid, and you should to.

Ben Garlock
6 min readDec 3, 2020

Once in a while you come across a technology and think “Man, I wish I had learned this sooner.” I’ve spent so many hours using the wrong tools to position elements on a DOM. Looking back it felt like I was using a rock to hammer in a nail.

CSS grid is intelligent, clean, and simple to learn and it will let you create beautiful websites in minutes.

CSS Grid Layout

You’ll need to create an index.html and index.css file to follow along. We’re going to start off with some basic HTML:

index.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="index.css" />
</head>
<body>
<div class="wrapper">
<div>
some text
</div>
<div>
some sidebar
</div>
<div>
some text
</div>
<div>
some sidebar
</div>
<div>
some sidebar
</div>
</div>

</body>
</html>

In order to better visualize each div, we will be adding an alternating grey background:

index.css:

.wrapper > div {
background: grey;
padding: 1em;
}

.wrapper > div:nth-child(odd) {
background: #ddd;
}

Setting Columns

A “grid” is just a plane with an X and Y axis that lets you create columns on the Y axis and rows on the X. We’ll start off with columns.

CSS Grid allows you to specify columns a few different ways. One is by using “grid-template-columns” with set percentages:

.wrapper {
display: grid;
grid-template-columns: 70% 30%;
}

Above, we’re creating two columns with a 70/30 split on the page. Although this works, it’s not really great practice to use % since it can cause problems with nested objects (which we’ll get to in a second)

Instead, you can use fractions or (fr)

Using fr

.wrapper {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
}

Above, we’ve now created THREE columns that all have equal spacing across the page. Feel free to experiment with these fractions numbers to see how your columns change width.

Using repeat

fr is great, but it’s not very DRY. What if we need to create 50 columns? For that we can use repeat:

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

Here the exact same result is produced, but we can save a lot of code if we need to start creating a ton of columns.

Using Gaps

Want to give your elements some breathing room? Gaps is useful for that. Think of it as margin but for grids:

.wrapper {
display: grid;
grid-template-columns: 1fr 1fr 1fr;

grid-column-gap: 1em; //only impacts columns
grid-row-gap: 1em; //only impacts rows
grid-gap: 1em; //impacts everything
}

Above, we’re applying a “gap” between ALL elements using grid-gap. You can apply this to just the columns by using gap-column-gap, or just the rows by using grid-row-gap. The above code is actually broken as you would only want to use one of these options.

Adjusting height with minmax (flexible height)

Now we’re getting into ROW attributes. If you want your rows to use a specific hight, but still be flexible to expand to accommodate various content (very common), you can use grid-auto-rows combined with minmax:

.wrapper {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-gap: 1em;

grid-auto-rows: minmax(100px, auto);
}

Nesting Grids

To review nested grids, we’re going to make some changes to our index.html file. Note the “Nested” class div:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="index.css" />
</head>
<body>
<div class="wrapper">
<div>
some text
</div>

<div class="nested">
<div>Nested text</div>
<div>Nested text</div>
<div>Nested text</div>
</div>

<div>
some text
</div>
<div>
some sidebar
</div>
<div>
some sidebar
</div>
</div>

</body>
</html>

In CSS within our nested div class, we can create a completely new grid:

.nested {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: 70px;
grid-gap: 1em;
padding: 1em
}

.nested > div {
border: black 1px solid;
}

Neat huh? There’s no limit to how many nested grids you could potentially have.

Grid Spanning

Grid spanning, or allowing elements to traverse across multiple columns and rows, might be the most challenging part of css grid to understand, but it’s not terribly difficult once you get the hang of it.

First, you will need to learn the concept of how “Lines” work in css grid:

Above is a simple illustration of these lines and how they work. If we wanted box one to span three columns, we would set this box to use lines 1/4 on the column axis. If we wanted box one to span all rows (two in this case), we would set it to use lines 1/3 on the row axis.

We need to update our index.html file one more time so we can create some custom div elements with individual class names. Note each div has a different “Box” class.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="index.css" />
</head>
<body>
<div class="wrapper">
<div class="box1">
box1
</div>

<div class="box2">
box2
</div>

<div class="box3">
box3
</div>
<div class="box4">
box4
</div>
<div class="box5">
box5
</div>
</div>

</body>
</html>

We’re going to reset our index.css file to only include the following code:

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

.wrapper > div {
background: grey;
padding: 1em;
}

.wrapper > div:nth-child(odd) {
background: #ddd;
}

That should give us this:

Our first example will be to have box 1 span columns 1 and 2:

.box1 {
grid-column: 1/3;
}

This will give us:

Not too bad right? If we wanted to create a navbar for example, we would set .box1 to “grid-column: 1/4” and it would have spanned the entire length of the page.

Spanning Rows

The same logic and syntax is used to allow elements to span rows. Instead of grid-colum, we use grid-row:

.box2 {
grid-column: 3;
grid-row: 1/3
}

Above, we’re allowing box2 to span two rows. You’ll notice CSS-grid automatically repositions all of the other elements in the DOM which is why this technology is so powerful.

Happy Coding!

--

--