CSS Grid Layout Guide: From Basics to Real Page Layouts
Practice4 minInnovialabs editorial team
In short
CSS Grid lays out elements in rows and columns at once: you define the grid tracks on the container and items drop into cells or named areas, which makes it ideal for page layouts.
What CSS Grid is
CSS Grid is a two-dimensional layout system: it controls rows and columns at the same time. Flexbox lines items up in one direction; Grid places them into a table of cells you can rearrange without touching the HTML.
.grid {
display: grid;
grid-template-columns: 200px 1fr;
gap: 24px;
}
That's two columns: the first is 200px, the second takes the rest. The container's direct children flow into the cells automatically.
Key concepts
| Concept | What it is |
|---|---|
| Track | A row or column of the grid |
| Line | The boundary between tracks, numbered from 1 |
| Cell | Where a row and a column intersect |
| Area | A rectangle spanning several cells |
gap | Space between tracks |
The fr unit
fr is a fraction of the free space in the container. 1fr 2fr splits space 1:2 after fixed sizes and gap are subtracted.
grid-template-columns: 240px 1fr 1fr;
The first column is fixed; the other two share the rest equally. Use repeat() for repeated tracks:
grid-template-columns: repeat(4, 1fr);
Placing items by lines
You can stretch an item across several tracks by naming lines:
.wide {
grid-column: 1 / 3; /* line 1 to line 3: two columns */
}
.tall {
grid-row: span 2; /* take two rows */
}
-1 means the last line of the explicit grid, so grid-column: 1 / -1 makes an item full width.
Named areas
grid-template-areas lets you draw the layout right in CSS:
.page {
display: grid;
grid-template-columns: 240px 1fr;
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
}
.page > header { grid-area: header; }
.page > aside { grid-area: sidebar; }
.page > main { grid-area: main; }
.page > footer { grid-area: footer; }
The code reads like a page diagram, and you can rearrange the layout by editing only the area strings.
auto-fit and minmax: responsive without media queries
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
The browser decides how many columns fit: each is at least 240px and stretches to a share of the free space. One column on a narrow screen, four or more on a wide one.
auto-fitcollapses empty columns, so items stretch to fill the width.auto-fillkeeps empty columns, so items stay at their size.
The implicit grid
If there are more items than cells in the grid you defined, Grid creates implicit rows. Size them with grid-auto-rows:
.grid {
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: minmax(160px, auto);
}
Each new row is at least 160px tall and grows if the content needs more.
Step by step: a responsive page layout
- Start with mobile — everything in one column:
.page {
display: grid;
gap: 16px;
grid-template-areas:
"header"
"main"
"sidebar"
"footer";
}
- On wide screens, rearrange the areas:
@media (min-width: 900px) {
.page {
grid-template-columns: 1fr 280px;
grid-template-areas:
"header header"
"main sidebar"
"footer footer";
}
}
- Assign
grid-areato each element as in the example above. The HTML stays the same.
Step by step: a card gallery
.gallery {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
gap: 20px;
}
.gallery img {
width: 100%;
aspect-ratio: 4 / 3;
object-fit: cover;
}
The cards reflow to fit the screen width, and aspect-ratio keeps the images consistent.
Common mistakes
1frwith long content. The minimum of1frisauto, so wide content inflates the column. Useminmax(0, 1fr).- Mismatched areas. Every string in
grid-template-areasneeds the same number of columns, and each area must be a rectangle. - Grid for everything. A simple row of buttons is easier with Flexbox.
- Visual order vs HTML order. Rearranging areas doesn't change the reading order for keyboard and screen reader users.
More details are in the MDN documentation.