In CSS Grid is a bidimensional CSS layout system that allows dividing a container into rows and columns.
We have seen Flexbox (Grid’s “brother”), which is a great tool for aligning things. However, sometimes we need to create more complex global structures at the full page level.
The main difference between both tools is:
- Flexbox is one-dimensional: It is designed to align and distribute space in one direction at a time (either in a horizontal row or a vertical column).
- Grid is two-dimensional: It is designed to work both width-wise and height-wise simultaneously.
Grid is the perfect tool for defining the general structure and main areas of a web page (like placing the header, sidebar, main content, and footer).
Defining the Grid: display: grid
To start drawing our layout board, the first step is to turn a parent container into a grid. Just like with its brother Flexbox, we activate the engine with a simple instruction:
.main-container {
display: grid;
}
By itself, this does almost nothing visible. We have simply just told the parent container to behave as a CSS Grid. We still need to define its properties 👇.
Rows and Columns (template)
We use the grid-template-columns and grid-template-rows properties to draw the lines of our grid, specifying the size of each “track”.
.my-grid {
display: grid;
/* We want 3 columns: the 1st at 200px, the 2nd flexible, and the 3rd at 100px */
grid-template-columns: 200px 1fr 100px;
/* We want 2 rows of 150px height each */
grid-template-rows: 150px 150px;
}
Notice the 1fr unit (one fraction). It is an exclusive Grid unit that tells the browser: “Take absolutely all the remaining free space on the screen and give it to this column”.
If you want to make 4 exactly equal columns, you don’t need to write 1fr 1fr 1fr 1fr. You can use the repeat(4, 1fr) function.
Adaptable Columns with minmax()
Grid becomes especially useful when we combine repeat() with minmax(). This allows us to create columns that adapt themselves to the available space.
.gallery {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
gap: 20px;
}
The phrase translates to: “create as many columns as fit, each with a minimum of 220px, and distribute the remaining space among them.”
This pattern is very useful for responsive card galleries. On large screens, several columns fit; on mobile, the cards automatically fall into a single column without writing a single Media Query.
Separating the Cells (gap)
Grid also supports the gap property to create spacing between our cells.
.my-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20px; /* Generates a perfect 20px separation in all directions */
}
It’s preferable to use gap instead of having to use margins on child elements. The container itself handles maintaining the distance between them automatically.
Spanning More Than One Cell (grid-column)
Sometimes we want an element to span two or three columns at once, like the typical large header (<header>) of a website.
To achieve this, instead of giving instructions to the parent, we go directly to the child element and tell it from where to where it should expand using the invisible “lines” of the grid.
.header {
/* Starts at dividing line 1 and ends at dividing line 4
(thus occupying 3 full columns contiguously) */
grid-column: 1 / 4;
background-color: darkblue;
color: white;
}
Naming Areas with grid-template-areas
For more complex layouts, Grid allows naming the areas. It’s a very visual way to describe the structure.
.layout {
display: grid;
grid-template-columns: 240px 1fr;
grid-template-areas:
"header header"
"sidebar content"
"footer footer";
gap: 20px;
}
header {
grid-area: header;
}
aside {
grid-area: sidebar;
}
main {
grid-area: content;
}
footer {
grid-area: footer;
}
grid-template-areas works especially well when you have clear semantic blocks: header, nav, main, aside, footer. Semantic HTML and CSS Grid get along quite well.
