
In previous examples, we have seen how to build layouts using as reference numeric values assigned to lines. Now we will explore some Best Practices that help us to simplify our job.
The first method is to define names to assign to columns templates and eventually to rows:
.container {
display: grid;
grid-template-rows: 100px 50px 300px 80px;
grid-template-columns: repeat(3, [container-start] 1fr) 300px [container-end];
}
With this method we can use names, we have previously defined, instead of numbers:
.header {
grid-column: container-start / container-end;
}
.navbar {
grid-column: container-start / container-end;
}
.footer {
grid-column: container-start / container-end;
}
The last approach is to assign names to areas: I consider this method not flexible enough, and it can be adapted with difficulties to more significant projects.
Using the property:
grid-template-areas
I assign names to areas, which are made up of cells groups, as we have seen before. For example, to define the template for .header, in the .container selector I assign the name of the area, grouping four cells:
grid-template-areas: "header header header header"
I recall the template of the area dedicated to the .header selector using the property:
grid-area: header;
This is the complete example:
.container {
display: grid;
grid-template-rows: 100px 50px 300px 80px;
grid-template-columns: repeat(3, 1fr) 300px;
grid-template-areas: "header header header header"
"navbar navbar navbar navbar"
"content content content sidebar"
"footer footer footer footer";
}
.header {
grid-area: header;
}
.navbar {
grid-area: navbar;
}
.content {
grid-area: content;
}
.sidebar {
grid-area: sidebar;
}
.footer {
grid-area: footer;
}
How to adapt the grid to mobile devices without using media queries
Let’s start with the following markup and its style sheet:
.container {
display: grid;
grid-template-rows: 100px 50px auto 80px;
grid-template-columns: repeat(3, 1fr) 300px;
}
.header {
grid-column: 1 / -1;
}
.navbar {
grid-column: 1 / -1;
}
.content {
grid-column: 1 / -2;
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: 125px;
gap: 20px;
&__item {
background: orange;
padding: 10px;
}
}
.footer {
grid-column: 1 / -1;
}
Please note that we assigned the value auto to define the height of the row, which contains the .content and the .sidebar
grid-template-rows: 100px 50px auto 80px;
This expedient insures that the height of the block will be adaptable to the number of contents contained in it.
The goal is to put the .sidebar under the .content in the mobile version and to make the blocks contained in .content arranged based on the width.
Let’s modify now the property grid-template-columns.
We will not specify the columns quantity (3), but we will use the property auto-fit, which will automatically generate traces based on space available.
grid-template-columns: repeat(3, 1fr) 300px;
grid-template-columns: repeat(auto-fit, 1fr) 300px;
Furthermore, thanks to the minmax function, we will specify a minimum width (300px) and a maximum one (1fr): on small displays the column width will be then 300px, but on those larger will be 1fr.
/* grid-template-columns: repeat(auto-fit, 1fr) 300px; */
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
We did not define a fixed width for the .sidebar, which maintains its position because we decided that the .content should occupy the space between rows 1 and -2:
.content {
grid-column: 1 / -2;
}
Regarding blocks contained in .content, we will delete the specific number of columns in favor of the function auto-fit, and of the definition of a minimum and a maximum height:
/* grid-template-columns: repeat(3, 1fr); */
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
The final code will be then as follows:
.container {
display: grid;
grid-template-rows: 100px 50px auto 80px;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
&>* {
color: #5c5c5c;
padding: 10px;
}
}
.header {
grid-column: 1 / -1;
background: coral;
}
.navbar {
grid-column: 1 / -1;
background: brown;
}
.content {
grid-column: 1 / -2;
background: gray;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
grid-auto-rows: 125px;
gap: 20px;
&__item {
background: orange;
color: #ffffff;
padding: 10px;
}
}
.sidebar {
background: orangered;
}
.footer {
grid-column: 1 / -1;
background: brown;
}
This is the result we obtained:

Flexbox vs. CSS Grid
The question which often arises is: what happens to Flexbox now? Actually, the two modules can be used in combination:
- with CSS Grid we can realize the supporting structure of the layout, and we can define the UI of elements that require simultaneous management of the placement on the two axis x and y
- Flexbox, on the other hand, is more suitable for handling a single axis at a time (e.g., navigation menus, vertical or horizontal lists, and so on).
To examine this issue in dept, check the link of the w3c specification, where the difference between the two modules is faced in the introduction.

Conclusions
There would be so much more to say because the CSS Grid specification is very wide and evolves continuously. Still, using the techniques we analyzed in this series of articles, we are able to make layouts thanks to CSS Grid!