For more complex layouts, you can opt to use a grid system.
A grid layout consists of a grid container and several grid items. The grid container must have its display
property set to grid
or inline-grid
. grid
creates a block-level container, and inline-grid
creates an inline-level container.
1<div class="container">
2 <div class="item">1</div>
3 <div class="item">2</div>
4 <div class="item">3</div>
5 <div class="item">4</div>
6 <div class="item">5</div>
7 <div class="item">6</div>
8</div>
1.container {
2 display: grid;
3}
All direct children of this container will automatically become grid items.
Grid columns
Open demo in new tabHint: You can edit this CodePen demo directly.
You can then specify how many columns you wish to create using the grid-template-columns
property. The property accepts any number of values. The number of values determines the number of columns, and the value itself determines the size of that column. For example:
1.container {
2 display: grid;
3 grid-template-columns: 100px 200px;
4}
5
6.item {
7 font-family: Georgia, "Times New Roman", Times, serif;
8 font-size: x-large;
9 text-align: center;
10 padding: 20px;
11 border: 1px solid orange;
12 background-color: bisque;
13}
We also added some styles for the grid items to make the grid look more pleasing, but it is not necessary for the purpose of this lesson, so they will be omitted in future examples.
In this example, we created two columns, the first one is 100px
wide, and the second one is 200px
wide. If you want more columns, simply add more values.
1.container {
2 display: grid;
3 grid-template-columns: 100px 200px 50px;
4}
If you want all columns to be equal in size, set the value to auto
.
1.container {
2 display: grid;
3 grid-template-columns: auto auto auto;
4}
This will allow the browser to choose an appropriate column size to fill the parent container.
Grid rows
Open demo in new tabThe grid rows, on the other hand, are created automatically. You can define row sizes using the grid-template-rows
property.
1.container {
2 display: grid;
3 grid-template-columns: auto auto auto;
4 grid-template-rows: 100px 150px;
5}
However, this property does not determine the number of rows in the grid. It only controls the row height. If you specify extra values, they will be ignored.
This is because, by default, the grid items will flow horizontally, meaning they will fill the first row, and if there is insufficient space, the remaining items will be moved to the second row, and so on.
Grid flow
Open demo in new tabThis default behavior is a bit problematic because sometimes, you only know how many rows you want, and you need the browser to create the columns automatically. In this case, you can change the flow direction of the grid items by setting grid-auto-flow
to column
.
Next, you can configure the gird rows, and this time, you can define the number of rows, as well as their sizes. The columns, on the other hand, will be created automatically.
1.container {
2 display: grid;
3 grid-auto-flow: column;
4
5 grid-template-rows: 100px 100px;
6 grid-template-columns: 100px 200px 300px;
7}
The grid template shorthand
Lastly, grid-template
is a shorthand property for grid-template-columns
and grid-template-rows
with the following syntax:
1grid-template: <row> <row> ... / <col> <col> ...;
1.container {
2 display: grid;
3 grid-template: 100px 150px / auto auto auto;
4}
Grid gaps
Open demo in new tabWhen designing a webpage, it is good to leave some space between elements so that they are not too close to each other. By using the grid layout, you can easily add equal spacing between the grid items instead of micromanaging their individual margin. For example:
1.container {
2 display: grid;
3 grid-template-columns: auto auto auto;
4 row-gap: 10px;
5 column-gap: 20px;
6}
Alternatively, you may use the shorthand property, gap
:
1.container {
2 display: grid;
3 grid-template-columns: auto auto auto;
4 gap: 10px 20px;
5}
If you want equal spacing for columns and rows, give a single value:
1.container {
2 display: grid;
3 grid-template-columns: auto auto auto;
4 gap: 10px;
5}
Spanning over multiple columns
Open demo in new tabYou can also customize individual grid items using CSS. In a real-life scenario, it is common for one grid item to take up multiple columns or rows. For example, you can define an item to span multiple columns by specifying a start point (grid-column-start
) and an end point (grid-column-end
).
1<div class="container">
2 <div class="item-2col">1</div>
3 <div class="item">2</div>
4 <div class="item">3</div>
5 <div class="item">4</div>
6 <div class="item">5</div>
7 <div class="item">6</div>
8 <div class="item">7</div>
9 <div class="item">8</div>
10</div>
1.container {
2 display: grid;
3 grid-template-columns: auto auto auto;
4 gap: 10px;
5}
6
7.item {
8 /* . . . */
9}
10
11.item-2col {
12 grid-column-start: 1;
13 grid-column-end: 3;
14}
Keep in mind that the numbers refer to the column line, not the column itself, as shown in the chart below.
As a result, for an item to span over two columns, it should start from 1
and end with 3
.
You can also use the shorthand property grid-column
to achieve the same result:
1.item-2col {
2 grid-column: 1 / 3;
3}
Instead of counting the grid lines, you can specify the number of columns you want the item to span over, and the browser will calculate the grid lines automatically.
1.item-2col {
2 grid-column: span 2;
3}
4
5.item-3col {
6 grid-column: span 3;
7}
Spanning over multiple rows
Similarly, you can define a grid item to span across multiple rows using the grid-row-start
and grid-row-end
properties, or the grid-row
shorthand.
1.item-2row {
2 grid-row-start: 1;
3 grid-row-end: 3;
4}
1.item-2row {
2 grid-row: 1 / 3;
3}
Spanning over an area
If an item needs to span over multiple rows and columns, you can use the grid-area
property instead, which is a shorthand for grid-row
and grid-column
. The property has the following syntax:
1grid-area: <row_start> / <col_start> / <row_end> / <col_end>
1.item-area {
2 grid-area: 1 / 1 / 3 / 3;
3}
Nested grid systems
In practice, you might need a more complex layout for your webpages. For example, your website might have a general layout with a header, footer, main content, as well as a sidebar.
1<div class="container">
2 <div class="nav">Navbar</div>
3 <div class="main">Main</div>
4 <div class="sidebar">Sidebar</div>
5 <div class="footer">Footer</div>
6</div>
1.container {
2 display: grid;
3 grid-template-columns: auto auto auto;
4}
5
6.container div {
7 font-family: Georgia, "Times New Roman", Times, serif;
8 font-size: x-large;
9 text-align: center;
10 padding: 20px;
11 border: 1px solid orange;
12 background-color: bisque;
13}
14
15.nav {
16 grid-column: 1 / 4;
17}
18
19.main {
20 grid-column: 1 / 3;
21 height: 50vh;
22}
23
24.sidebar {
25 grid-column: 3 / 4;
26 height: 50vh;
27}
28
29.footer {
30 grid-column: 1 / 4;
31}
And inside the main content section, you might need a 3x3
grid for your blog articles, and inside the sidebar, you might need another grid for the subsections.
1<div class="container">
2 <div class="nav">Navbar</div>
3 <div class="main">
4 <div class="post">Post</div>
5 <div class="post">Post</div>
6 <div class="post">Post</div>
7 <div class="post">Post</div>
8 <div class="post">Post</div>
9 <div class="post">Post</div>
10 </div>
11 <div class="sidebar">
12 <div class="section">Section</div>
13 <div class="section">Section</div>
14 <div class="section">Section</div>
15 </div>
16 <div class="footer">Footer</div>
17</div>
1.container {
2 display: grid;
3 grid-template-columns: auto auto auto;
4}
5
6.container div {
7 font-family: Georgia, "Times New Roman", Times, serif;
8 font-size: x-large;
9 text-align: center;
10 padding: 20px;
11 border: 1px solid orange;
12 background-color: bisque;
13}
14
15.nav {
16 grid-column: 1 / 4;
17}
18
19.main {
20 grid-column: 1 / 3;
21 height: 50vh;
22
23 display: grid;
24 grid-template-columns: auto auto auto;
25 gap: 10px;
26}
27
28.sidebar {
29 grid-column: 3 / 4;
30 height: 50vh;
31
32 display: grid;
33 grid-template-columns: auto;
34 gap: 10px;
35}
36
37.footer {
38 grid-column: 1 / 4;
39}
As you can see, this system isn't simple. As the webpage becomes increasingly complex, this grid system will become quite messy and difficult to maintain.
A better way to do things is to have a universal grid system. You can make sure all grid systems have 12 columns, and you only have to worry about how many columns each item has to span over.
For example, you can redesign the general layout of the webpage like this:
1<div class="grid">
2 <div class="col-span-12">Nav</div>
3 <div class="col-span-8">Main</div>
4 <div class="col-span-4">Sidebar</div>
5 <div class="col-span-12">Footer</div>
6</div>
1.grid {
2 display: grid;
3 grid-template-columns: repeat(12, auto);
4 gap: 10px;
5}
6
7.grid div {
8 font-family: Georgia, "Times New Roman", Times, serif;
9 font-size: x-large;
10 text-align: center;
11 padding: 20px;
12 border: 1px solid orange;
13 background-color: bisque;
14}
15
16.col-span-1 {
17 grid-column: span 1;
18}
19
20/* . . . */
21
22.col-span-12 {
23 grid-column: span 12;
24}
The best part about this system is that the defined grid styles can be reused. You can use it to create the 3x3
blog grid.
1<div class="col-span-8 grid">
2 <div class="col-span-4">Post</div>
3 <div class="col-span-4">Post</div>
4 <div class="col-span-4">Post</div>
5 <div class="col-span-4">Post</div>
6 <div class="col-span-4">Post</div>
7 <div class="col-span-4">Post</div>
8 <div class="col-span-4">Post</div>
9 <div class="col-span-4">Post</div>
10 <div class="col-span-4">Post</div>
11</div>
Or the sidebar:
1<div class="col-span-4 grid">
2 <div class="col-span-12">Section</div>
3 <div class="col-span-12">Section</div>
4 <div class="col-span-12">Section</div>
5</div>