Overview
CSS Grid is the first layout system designed specifically for two-dimensional layouts. It lets you control rows and columns simultaneously, place items anywhere on the grid, and create responsive designs without media query gymnastics. This tutorial covers the fundamentals with practical examples.
Grid vs Flexbox
| Aspect | Grid | Flexbox |
|---|---|---|
| Dimensions | Rows and columns | Single axis |
| Item placement | Explicit line-based positioning | Flow along an axis |
| Best use case | Page layouts, dashboards, image galleries | Toolbars, rows of cards, centering |
Defining a Grid
.container {
display: grid;
grid-template-columns: 200px 1fr 200px;
grid-template-rows: auto 1fr auto;
gap: 16px;
}
This creates a three-column layout with fixed sidebars and a flexible center column, plus a header, content area, and footer.
The fr Unit
fr represents a fraction of the available space. It is unique to Grid and replaces percentage-based math.
.container {
display: grid;
grid-template-columns: 1fr 2fr 1fr;
}
The middle column is twice as wide as the side columns.
repeat() and minmax()
/* Five equal columns */
grid-template-columns: repeat(5, 1fr);
/* Responsive columns that never shrink below 250px */
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
The auto-fit and auto-fill keywords create as many columns as will fit in the container — the foundation of responsive card grids without media queries.
| Keyword | Behavior |
|---|---|
auto-fit | Collapses empty tracks so items stretch to fill the row |
auto-fill | Keeps empty tracks, so items keep their column width |
Placing Items
.header {
grid-column: 1 / -1;
}
.sidebar {
grid-row: 2 / 4;
grid-column: 1 / 2;
}
.content {
grid-column: 2 / 4;
}
Lines are numbered starting at 1. Negative numbers count from the end, so -1 is the last line.
Named Lines and Areas
.container {
display: grid;
grid-template-areas:
"header header header"
"sidebar main main"
"footer footer footer";
grid-template-columns: 200px 1fr 1fr;
grid-template-rows: auto 1fr auto;
}
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main { grid-area: main; }
.footer { grid-area: footer; }
grid-template-areas produces the most readable layout code and is easy to reshape for responsive breakpoints.
Alignment
| Property | Axis | Common values |
|---|---|---|
justify-items | Inline (columns) | start, center, end, stretch |
align-items | Block (rows) | Same as above |
justify-content | Whole grid inline | start, center, space-between |
align-content | Whole grid block | Same as above |
place-items | Both axes | Shorthand for align-items + justify-items |
Practical Example: Responsive Gallery
.gallery {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 1rem;
}
.gallery img {
width: 100%;
aspect-ratio: 4 / 3;
object-fit: cover;
}
.featured {
grid-column: span 2;
grid-row: span 2;
}
Common Mistakes
- Applying grid properties to items instead of the container.
grid-template-columnsbelongs on the grid parent. - Forgetting
gap. Usegapinstead of margins; it does not add outer spacing. - Over-nesting grids. A nested grid inherits nothing; define columns explicitly.
- Using Grid for single-axis layouts. Flexbox is simpler for a row of buttons.
