In this tutorial, I will cover the basics of the CSS grid layout with example scenarios. CSS Grid is supported by almost all modern browsers now, and it is ready to be used in production. Unlike other layout methods such as flexbox, the grid layout gives you two degrees of freedom, which makes it so versatile that positioning the elements is just a breeze.
HTML Structure for the CSS Grid Layout
In order to use the CSS Grid layout, your HTML elements should have a specific structure.
You need to wrap the elements that you want to control within a parent container DIV.
<div class="wrapper"> <div class="div1">1</div> <div class="div2">2</div> <div class="div3">3</div> <div class="div4">4</div> </div>
Let’s add some styling for our DIVs so that we can distinguish them easily.
Also, set the display: grid
in your wrapper
DIV so that we can start using the grid layout.
.wrapper > div background-color: orange; border: 1px black solid; .wrapper > div:nth-child(odd) background-color: indianred; .wrapper display: grid
From this point on, all the styling will go into the wrapper
DIV. If we ever want to control the child DIVs at any point, then we will be adding grid-specific styling rules for the specific child DIV.
Rules on Parent DIV
The first things we need to learn about the grid layout are grid-template-columns
and grid-template-rows
. Those two rules basically control how your grid is shaped.
The value of these rules can be a length, a percentage, or a fraction of the free space in the grid. You can also set any value to auto
, which fills up the remaining space.
Let’s see some examples below.
Grid-template-columns & Grid-template-rows
grid-template-columns
.wrapper display: grid; grid-template-columns: 100px 100px 100px
.wrapper display: grid; grid-template-columns: 100px auto 100px
.wrapper display: grid; grid-template-columns: 1fr 1fr 1fr 1fr;
grid-template-columns & grid-template-rows
Let’s start building a real grid, in which we have control over both columns and rows.
.wrapper display: grid; grid-template-columns: 1fr 1fr; grid-template-rows: 50px 50px;
.wrapper display: grid; grid-template-columns: 100px 20px 250px; grid-template-rows: 150px 40px;
Here I just added two more child DIVs to the HTML for the same CSS.
Repeat a grid-template Pattern
If you have a repeating pattern for grid-template
, you can just use repeat and tell it how many times to repeat the same pattern.
For instance, say you have 12 elements, and you want to lay them out horizontally with equal width. You could repeat 1fr
12 times inside grid-template-columns
, which is not effective. So, instead, you can use repeat(12, 1fr)
.
.wrapper display: grid; grid-template-columns: repeat(12, 1fr)
Likewise, you can repeat a pattern.
.wrapper display: grid; grid-template-columns: repeat(4, 1fr 5fr 10fr);
Grid-auto-columns & Grid-auto-rows
This rule helps you to set the width and height of grid cells.
If you don’t set this rule, your grid rows and columns will expand with the content.
.wrapper display: grid; grid-template-columns: repeat(4, 1fr); grid-auto-rows: 100px;
.wrapper display: grid; grid-template-columns: repeat(4, 1fr); grid-auto-rows: 20px 80px;
One nice feature to use with grid-auto
rule is the minmax
function.
You simply set the minimum size as the first parameter and the maximum as the second parameter. If you set auto
for the second parameter, you get a responsive cell size.
.wrapper display: grid; grid-template-columns: repeat(4, 1fr); grid-auto-rows: minmax(50px, auto)
Below you see two different DIV contents with the same CSS rules.
Grid-gap
As the name implies, this rule creates a gap between grid cells.
If you use grid-gap: 5px
, you get a 5px gap between each cell. Alternatively, you can only set the row or column gaps, with grid-row-gap: 5px
and grid-column-gap: 5px
respectively.
.wrapper display: grid; grid-template-columns: repeat(4, 1fr); grid-auto-rows: minmax(50px, auto); grid-gap: 5px;
Rules on Child DIVs
So far, we’ve only focused on the shape of the grid and items just flowed in the grid. Now we will learn how to control each item individually.
In order to position the items, we use grid lines as a reference. Below you see the row and column lines in black and orange respectively for a 2×4 grid.
We will use the grid-column
and grid-row
rules with line numbers to position the elements.
For example, if we set grid-column: 1/3
for the first child div, it will use the first two cells in the grid.
Consider the HTML and CSS below:
<div class="wrapper"> <div class="div1">1</div> <div class="div2">2</div> <div class="div3">3</div> <div class="div4">4</div> <div class="div5">5</div> <div class="div6">6</div> <div class="div7">7</div> <div class="div8">8</div> </div>
.wrapper display: grid; grid-template-columns: repeat(4, 1fr); grid-auto-rows: 100px; grid-gap: 5px;
We have four equally sized columns and eight elements in the wrapper
DIV.
.div1 grid-column: 1/3;
.div1 grid-column: 1/3; grid-row: 1/3;
You can also combine these two rules into a single rule, grid-area: rowStart/columnStart/rowEnd/columnEnd
.
.div1 grid-area: 2/2/3/4;
As illustrated in the above example, elements are not bound to the HTML structure. Notice how the first element is repositioned with the grid-area
rule.
Grid-area & grid-template-areas
You can name each child element and use these names to create your grid. This is really powerful, and it makes doing layout more intuitive.
So we define a DIV for each element we are planning to place in our grid system.
I am planning to have a header, leftColumn, rightColumn, middleTop, middleBottom, and a footer.
So in my HTML I need that many child DIVs. The class names can be anything.
<div class="wrapper"> <div class="header">Header</div> <div class="leftCol">LeftCol</div> <div class="rightCol">RightCol</div> <div class="midTop">midTop</div> <div class="midBottom">midBottom</div> <div class="footer">Footer</div> </div>
Then, inside my CSS, I set the grid-area
names. Those names can be anything; they are not supposed to match the class names.
.header grid-area: header; background-color: LightSeaGreen ; .leftCol grid-area: leftCol; background-color: orange; .rightCol grid-area: rightCol; background-color: lightblue; .midTop grid-area: midTop; background-color: lightgrey; .midBottom grid-area: midBottom; background-color: pink; .footer grid-area: footer; background-color: lightgreen;
Then, inside my wrapper
DIV, I use the grid-template-areas
rule to lay out those elements by referring to their defined names.
Notice that I have a 4×4 grid.
.wrapper display: grid; grid-template-columns: 1fr 4fr 4fr 1fr; grid-template-rows: 50px 100px 100px 30px; grid-template-areas: "header header header header" "leftCol midTop midTop rightCol" "leftCol midBottom midBottom rightCol" "footer footer footer footer"; grid-gap: 5px;
If, for example, I want the footer to take only two columns and be centered, then I simply replace the first and the last appearance of footer with a dot (.
) in grid-template-areas
.
.wrapper display: grid; grid-template-columns: 1fr 4fr 4fr 1fr; grid-template-rows: 50px 100px 100px 30px; grid-template-areas: "header header header header" "leftCol midTop midTop rightCol" "leftCol midBottom midBottom rightCol" ". footer footer ."; grid-gap: 5px;
Conclusion
CSS Grid has tons of rules, and I only covered the most useful ones in this tutorial. You can still dig into MDN Web Docs or any other sources for the full list of grid properties and functions.