CSS: Grid Tutorial
Overview
In this tutorial, we will start off by walking through the big-picture things you need to know about grid, then get into some ways to get more detailed in how you control your layout with it. This is meant to be an introduction that positions you to implement Grid for a simple layout. It should also equip you with some resources for exploring more on your own.
As you read through each section and look at the associated CodePen, make sure to stop and read the CSS in each CodePen even if you aren’t given a task for it.
As you work through this, please keep in mind that there are always many ways of solving a problem in programming. There may be cases where one developer solves a problem with Flexbox, another solves the same problem with Grid and another doesn’t use either. Here’s another very possible situation: both developers choose to use Grid, but implement Grid differently to achieve the same layout. There is no one or right way. That makes the learning goals of this feel a little vague; you can implement Grid without knowing much or even writing much code. It will be up to you on how deep you want to go!
Can I even use Grid?
Can I Use? provides data on support for various features across the major browsers.</p>
Why use Grid?
CSS has always been used to layout web pages, but was never very good at it. Flexbox helped out, but it’s intended for simpler one-dimensional layouts, not complex two-dimensional ones (Flexbox and Grid actually work very well together). Can you imagine building this with Flexbox? Or this?
Set Up
Download and open the Firefox browser. Firefox has better developer tools for Grid, so we’d recommend using this anytime you are using Grid in development.
Normal Block Elements
Normal block level elements, like the section
s and article
s we’ve all come to know and love, will take up the entire width of the page and the height they need to fit content (unless specified otherwise). They would look like this:
Note: Another stylesheet was imported into the CodePens we will be using today - that’s why you don’t see the rules for the colors and background colors!
See the Pen Grid Lab by Turing School (@turing-school) on CodePen.
What happens if we turn on Grid?
Similar to implementing Flexbox, we apply display: grid;
to the parent element, whose direct children we want to control using Grid. Applying it alone does nothing, as you can see in the CodePen below. We need to specify our grid-template.
See the Pen Grid Lab 2 by Turing School (@turing-school) on CodePen.
The grid-template-columns
Property
We can give each column fixed units.
See the Pen Grid Lab 3 by Turing School (@turing-school) on CodePen.
Investigate Marvel
This declaration is applied to the div that holds all the images.
grid-template-columns: minmax(200px, 1.167fr) 0.45fr 0.25fr 0.3fr 0.8fr;
This tells us there are 5 columns, because 5 different values are making up the value for the grid-template-columns
property. When using the inspector, we can see them:
Two new things you probably noticed here:
minmax()
fr
(read about in the next section)
The fr
Unit
We can also use a unit that will take up a fraction of the grid - fr
. In the example below, we have grid-template-columns: 1fr 1fr 3fr;
- this means we will have 3 columns total. The first will be one fraction of the width of the container, the second will also be one fraction, and the third will be three fractions. Together, we have 5 fractions - so the first two columns will take up 1/5 or 20% each, and the third will take up 3/5 or 60% each.
See the Pen Grid Lab 4 by Turing School (@turing-school) on CodePen.
Try It
Fork the CodePen above.
- Change the value provided to
grid-template-columns
to2fr 2fr 2fr
. What happens? - Change the value a few more times until you feel like you understand how the
fr
unit works.
If you need some more time with it, here is a great video and here is another written explanation.
The grid-template-rows
Property
So far, our grid rows have been implicitly set. But you can also explicitly set them using this property! In the example above, we provided the grid-template-rows
with three units in the value: 100px 50px 200px
. The first unit defines the height of the first row, the second the second row, and the third the third row.
See the Pen grid-template-rows by Turing School (@turing-school) on CodePen.
Marvel’s Rows
Take a look at the way the Marvel site used grid-template-row
:
.grid-2 {
grid-template-columns: minmax(200px, 1.167fr) 0.45fr 0.25fr 0.3fr 0.8fr;
}
The image above leaves out the first row which is why we start with row 2 rather than 1. Notice that the image on the far left-top took up three rows, but the bottom row all had one-row-high images. This is why Grid is so powerful! It also means it’s essential to plan out how Grid will be used before writing any code.
Try It
Fork the CodePen above.
- Change the value provided to
grid-template-rows
to1fr 3fr 1fr
. You should see thatfr
works the same way here. - Change the value to
100px 200px
. What happens to the height of the third row? Why do you think that is?
Control individual items with grid-template-areas
Now that we have explored a simple layout of columns and row, let’s get into some of the fun details that really make grid powerful.
The grid-template-areas
property allows you to specify areas of your page. It doesn’t automatically associate specific elements with a given area.
First, we set up our template:
.container {
grid-template-areas:
"sidebar main main"
"sidebar footer footer";
}
The code snippet above creates 6 template areas made up of 2 rows, each with three columns. Each area has a name attached to it. Notice that the same name can be used more than once.
We will use that name to reference it from the item we want to live in that area:
.box1 {
grid-area: sidebar;
}
.box2 {
grid-area: main;
}
.box3 {
grid-area: footer;
}
.box1
will take up the entire first column since it’s grid-area
is assigned to sidebar. .box2
will take up the rest of the top row, and .box3
will take up the rest of the bottom row.
Note: sidebar, main, and footer were not special or reserved keywords of any kind. The developer who creates the grid has full control over what to name these. We could use a, b, and c. We generally choose names that describe the content that will fit it, or location if dealing with dynamic content!
See the Pen Grid Lab 13 by Turing School (@turing-school) on CodePen.
Try It
Fork the CodePen above.
- Change the “sidebar” in the second row to “footer”. What happens? Is that what you expected?
- In the HTML, add
<article class="box box4">new box!</article>
above the footer. Modify your template to have three rows, the middle row being “middle middle middle”. Then, write the code necessary to have.box4
take up the entire middle row. - Now, add another article to your HTML, this time with the
.box5
class..box4
should take up the first two columns of the middle row, and.box5
should live in the last column of the middle row.
Take a Pom
Maybe watch a video about Dog Grooming? Or take a walk around the block?
Before moving on to the next section - asses your level of comfort with the content up until now. If you are feeling foggy or nervous to go deeper, whip up your own CodePen and start from scratch. Referencing docs or this document is great but copy and pasting won’t help you much! If you do feel ready to move on - that’s cool too! The next section will provide some ways you can establish even more control over your layout.
The grid-gap
Properties
grid-gap
provides some breathing room around grid items. This can be handy! grid-gap
is a little generic, as you can see in the CodePen above, this adds a gap to both columns and rows. To be more specific, we can use grid-column-gap
and grid-row-gap
.
See the Pen Grid Lab 7 by Turing School (@turing-school) on CodePen.
Try It
In the CodePen above,
- Change the value provided to
grid-gap
to see how that changes the appearance. - Remove the
grid-gap
declaration and addgrid-column-gap: 20px;
- what happens? Try usinggrid-row-gap
, too!
Changing the size and position of elements
In the CodePen below, we can see that .box1
is taking up the first two “cells” of the far-left column. Let’s look at the rule for .box1
:
.box1 {
grid-row: span 2;
}
Let’s break this down:
grid-row
is a property on the specific item we want to control. It allows us to define how much of the row we want this item to take up.span 2
tells this item to take up two columns of the row it was originally in- We can see that it
.box1
is now taking up it’s original “space” as well as the space below it
Similiarly, we see that .box8
is taking up the left and middle “cells” of the bottom row.
.box8 {
grid-column: span 2;
}
See the Pen Grid Lab 8 by Turing School (@turing-school) on CodePen.
Next Up - we can provide two values! Here’s an example:
.box1 {
grid-row: 2 / span 2;
}
Let’s break it down:
- the
2
before the slash indicates the row that the element should start on - the
span 2
after the slash indicates the row should end on, or how long it should span
Note: -1
will refer to the end of the column or row, no matter the number of columns or rows.
See the Pen Grid Lab 9 by Turing School (@turing-school) on CodePen.
Try It
In the CodePen above,
- Change the value provided to
grid-row
for.box1
to1 / span 2
. - Now try
1 / span 3
- Now try
2 / span 1
- What happens when you try
2 / span 3
? Not what you expected maybe? Why did that happen?
Dry it up using repeat()
If you are going to sett all columns or all rows to the same height/width, repeat
can be a clean way to communicate that (especially if you have a big grid)!
See the Pen Grid Lab 5 by Turing School (@turing-school) on CodePen.
Fill in the gaps using grid-auto-flow: dense
Note that this will change the position of elements and therefore may not be great for accessibility.
See the Pen Grid Lab 10 by Turing School (@turing-school) on CodePen.
Utilizing auto-fit
auto-fit
allows us to make our grid adaptive!
See the Pen Grid Lab 11 by Turing School (@turing-school) on CodePen.
Adding minmax
The addition of minmax
makes things responsive!
See the Pen Grid Lab 12 by Turing School (@turing-school) on CodePen.