CSS Grid Examples from Learn CSS Grid Course at Scrimba
This blog post contains my notes from the great interactive video course Learn CSS Grid for free authored by Per Harald Borgen. Please watch the video courses. They explain CSS Grid in a very easy to understand way.
The videos are interactive. The watcher can edit the source code at any time directly on the video screen and see the effects immediately.
Table of Contents
v01: Stacking without CSS Grid
cat cssgrid01.html
##> <html>
##> <head>
##> <link rel="stylesheet" href="basic.css">
##> <style>
##> .container {
##> display: grid;
##> }
##> </style>
##> </head>
##> <body>
##> <div class="container">
##> <div>1</div>
##> <div>2</div>
##> <div>3</div>
##> <div>4</div>
##> <div>5</div>
##> <div>6</div>
##> </div>
##> </body>
##> </html>
##>
v02: Basic Layout with CSS Grid
Sizes of columns and rows are specified with: grid-template-columns
and grid-template-rows
.container {
display: grid;
grid-template-columns: 100px auto;
grid-template-rows: 50px 50px 100px;
grid-gap: 3px;
}
Note that, auto
makes the second column responsive.
Let’s convert from 3 columns x 2 rows to 2 columns x 3 rows:
grid-template-columns: 100px auto;
grid-template-rows: 50px 50px 100px;
We can move the style code into a separate css file:
<link rel="stylesheet" href="cssgrid04.css">
cat cssgrid04.css
##> .container {
##> display: grid;
##> grid-template-columns: 100px auto;
##> grid-template-rows: 50px 50px 100px;
##> grid-gap: 3px;
##> }
##>
The result is the same.
v03: Fraction Units and repeat()
2fr
column is twice as large as 1fr
column.
grid-template-columns: 1fr 2fr 1fr;
grid-template-rows: 50px 50px;
To make all columns equal in width, we can either do this:
grid-template-columns: 1fr 1fr 1fr;
or this:
grid-template-columns: repeat(3, 1fr);
Let’s make 6 columns:
grid-template-columns: repeat(6, 1fr);
grid-template-rows: 50px 50px;
We can use repeat()
also with rows:
grid-template-rows: repeat(2, 50px);
As shorthand, we can specify column and row sizes in one line:
grid-template: repeat(2, 50px) / repeat(3, 1fr);
v04: Positioning items
cat cssgrid09.html | sed -n '/container/,+5 p'
##> <div class="container">
##> <div class="header">HEADER</div>
##> <div class="menu">MENU</div>
##> <div class="content">CONTENT</div>
##> <div class="footer">FOOTER</div>
##> </div>
grid-template: 40px 40px / repeat(2, 1fr);
Let’s give content
more area to expand:
grid-template: 40px 200px 40px / repeat(2, 1fr);
But we need to separate content
section from footer
section.
.header {
grid-column-start: 1;
grid-column-end: 3;
}
.menu {}
.content {}
.footer {
grid-column-start: 1;
grid-column-end: 3;
}
Let’s make content
section wider too:
grid-template: 40px 200px 40px / 1fr 4fr;
Alternatively, we can write in shorthand form:
grid-column: 1 / 3;
Or:
grid-column: 1 / span 2;
Or:
grid-column: 1 / -1;
-1
is useful if we may change number of columns later.
Let’s use 12 column layout:
grid-template-columns: repeat(12, 1fr);
We don’t need to change the followings:
grid-column: 1 / -1;
But we need to specify the positioning of content
.content {
grid-column: 2 / -1;
}
Now, let’s change the overall layout. Let the menu
section start from the top and slide header
section beside it.
To do it, header
should start from 2. column border and menu
should start from 1. row border:
.header {
grid-column: 2 / -1;
}
.menu {
grid-row: 1 / 3;
}
v05: Template Areas
“Template Area” feature allows to experiment with different layouts very rapidly.
cat cssgrid13.css
##> .container {
##> height: 100%;
##> display: grid;
##> grid-template-columns: repeat(12, 1fr);
##> grid-template-rows: 40px auto 40px;
##> grid-gap: 3px;
##> grid-template-areas:
##> "h h h h h h h h h h h h"
##> "m c c c c c c c c c c c"
##> "f f f f f f f f f f f f"
##> }
##>
##> .header {
##> grid-area: h;
##> }
##>
##> .menu {
##> grid-area: m;
##> }
##>
##> .content {
##> grid-area: c;
##> }
##>
##> .footer {
##> grid-area: f;
##> }
##>
##>
The layout of the page is specified with the following expression:
grid-template-areas:
"h h h h h h h h h h h h"
"m c c c c c c c c c c c"
"f f f f f f f f f f f f"
h m c f
are header menu content footer
sections respectively.
To experiment with different layouts, let’s change top h and bottom f with m:
grid-template-areas:
"m h h h h h h h h h h h"
"m c c c c c c c c c c c"
"m f f f f f f f f f f f"
.
dots will make blank cells
But all sections should be rectangular.
grid-template-areas:
"m . . h h h h h h h h h"
"m c c c c c c c c c c c"
"m f f f f f f f f f f f"
v06 Auto-fit and minmax
auto-fit
adjusts the number of columns according to the size of the window:
grid-template-columns: repeat(auto-fit, 100px);
Instead of 100px
we can use 1fr
together with minmax. A column will be at least 100px
and at max 1fr
.
grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
v07 Implicit rows
Note that, in the previous examples the rows after second row have a broken height. Let’s define default size for all rows:
grid-auto-rows: 100px;
instead of:
grid-template-rows: repeat(2, 100px);
–>
grid-auto-rows: 100px;
v08 An awesome image grid
@tbd
.horizontal {
grid-column: span 2;
}
.vertical {
grid-row: span 2;
}
.big {
grid-column: span 2;
grid-row: span 2;
}
blank spots
grid-auto-flow: dense;
source order independence
v09 Named Lines
Until now, we specified the layout using the border line numbers such as 1/3
where 1
is the starting column border line and 3 is the ending column border line:
.container {
display: grid;
grid-template-columns: 1fr 5fr;
grid-template-rows: 40px auto 40px;
}
.header {
grid-column: 1 / 3;
}
...
Now, instead of line numbers we can give names to the lines:
grid-template-columns: [main-start] 1fr [content-start] 5fr [content-end main-end];
Here, [main-start] is the name of first line. [content-start] is the name of second line.
Note that, third line has two names: content-end
and main-end
.
So, instead of 1 / 3
we can say main-start / main-end
.header {
grid-column: main-start / main-end;
}
.content {
grid-column: content-start / content-end;
}
We can further simplify these expressions by eliminating -start
and -end
words:
.header {
grid-column: main;
}
.content {
grid-column: content;
}
We can do the same also for naming row lines:
.container {
grid-template-columns: [main-start] 1fr [content-start] 5fr [content-end main-end];
grid-template-rows: [main-start] 40px [content-start] auto [content-end] 40px [main-end];
...
.footer {
grid-column: main;
}
We can still make one more simplification. Note that, content
section’s 4 borders are named as content
. So we can say:
.content {
grid-area: content;
}
But we cannot do this for footer
section. Because footer’s starting row is named as content-end
whereas its ending row is named as main-end
. Since, their names are different, we cannot specify it as a grid-area
.
v10: justify-content and align-content
Use justify-content
to justify content as start
, center
or end
:
.container {
justify-content: end;
...
align-content
aligns the elements vertically:
align-content: end;
To distribute elements around space use: space-evenly
space-between
space-around
justify-content: space-between;
v11: auto-fit vs. auto-fill
There is a very slight difference between auto-fit
and auto-fill
:
.container {
grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
grid-template-rows: repeat(2, 100px);
}
.container2 {
grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
grid-template-rows: repeat(2, 100px);
}
When we increase the width, both behave similarly:
But if we keep expanding, then they differ: