CSS Grid Basics
Introduction
CSS Grid is the modern layout system for two-dimensional structure: rows and columns together. It is ideal for page sections, dashboard blocks, galleries, and card matrices that need clear alignment in both directions. This chapter introduces Grid fundamentals so you can build stable layouts without float hacks or excessive nesting.
Prerequisites
- Solid understanding of normal flow and box model
- Basic Flexbox knowledge
- Familiarity with responsive sizing concepts
Why Grid
Flexbox is great for one axis at a time. Grid is built for:
- columns and rows at once
- precise track sizing
- predictable alignment across multiple items
Common use cases:
- full page shell (header/sidebar/main/footer)
- product/card grids
- image galleries
- dashboard panels
Enable Grid Layout
Apply Grid on the container:
.layout {
display: grid;
}Direct children become grid items automatically.
Grid does nothing useful until you define tracks (columns/rows).
Define Columns with grid-template-columns
Basic fixed columns:
.layout {
display: grid;
grid-template-columns: 240px 1fr;
}Meaning:
- first column fixed at
240px - second column takes remaining space
Three equal columns:
.cards {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
}Define Rows with grid-template-rows
You can explicitly size rows:
.dashboard {
display: grid;
grid-template-rows: auto 1fr auto;
}Useful for app shells where header and footer are content-sized, with flexible middle area.
If rows are not explicitly defined, Grid creates implicit rows as needed.
fr Unit
fr means “fraction of remaining free space.”
grid-template-columns: 1fr 2fr;Second column gets twice the free space of the first.
Why fr is practical:
- cleaner than percentage math
- adapts naturally with container width
Gap in Grid
Use gap for spacing between tracks:
.cards {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 1rem;
}You can also use:
row-gapcolumn-gap
Prefer gap over margin hacks for internal grid spacing.
repeat() for Cleaner Syntax
Instead of writing repeated columns:
grid-template-columns: 1fr 1fr 1fr 1fr;Use:
grid-template-columns: repeat(4, 1fr);This is easier to read and maintain.
minmax() for Flexible Tracks
minmax(min, max) sets a track with lower/upper bounds.
grid-template-columns: repeat(3, minmax(180px, 1fr));Meaning:
- each column should not shrink below
180px - can grow up to equal fractional size
Very useful in responsive card layouts.
Auto-Fit and Auto-Fill (Preview)
A powerful responsive pattern:
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));Behavior:
- create as many columns as fit container
- wrap naturally as viewport changes
For beginners, auto-fit + minmax is one of the highest-value Grid patterns.
Implicit Rows and grid-auto-rows
When item count exceeds explicit tracks, Grid creates implicit rows.
You can size them:
.gallery {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: 180px;
}This keeps generated rows visually consistent.
Basic Alignment in Grid Container
Container-level alignment properties include:
justify-items(inline axis per item)align-items(block axis per item)place-items(shorthand)
Example:
.grid {
display: grid;
justify-items: stretch;
align-items: start;
}You will use item placement/alignment in the next chapter more deeply.
Practical Starter Patterns
Pattern 1: Simple card matrix
.cards {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
gap: 1rem;
}Pattern 2: Sidebar + content shell
.app {
display: grid;
grid-template-columns: 260px 1fr;
gap: 1rem;
}Pattern 3: Three-row app structure
.page {
min-height: 100dvh;
display: grid;
grid-template-rows: auto 1fr auto;
}These patterns cover many real product interfaces.
Tip
Grid First for Two-Dimensional Layout
If you are managing both rows and columns together, start with Grid and only add Flexbox inside components where one-axis alignment is needed.
Common Mistakes
| Mistake | Why it hurts | Better approach |
|---|---|---|
| Using fixed pixel columns everywhere | Breaks on smaller screens | Use fr, minmax, and responsive patterns |
| Spacing with child margins only | Uneven internal rhythm | Use gap on grid container |
| Overcomplicated nested wrappers | Hard to maintain | Let Grid handle high-level structure |
| Ignoring implicit row behavior | Unexpected row heights | Define grid-auto-rows where needed |
| Using Grid for tiny one-axis alignments | Unnecessary complexity | Use Flexbox inside simple components |
Debugging Grid in DevTools
When layout looks wrong:
- inspect container and confirm
display: grid - check computed track definitions
- toggle Grid overlay in DevTools
- verify item count vs explicit/implicit tracks
- test with narrow viewport for overflow/wrap behavior
Grid overlays are extremely helpful for visualizing tracks and gaps.
Mini Exercise
- Build a card list with
repeat(auto-fit, minmax(220px, 1fr)) - Add
gap: 1rem - Resize viewport and observe column changes
- Build a page shell with
grid-template-columns: 240px 1fr - Add top/bottom sections using row tracks
- Inspect both layouts with DevTools Grid overlays
FAQ
Is Grid better than Flexbox?
Neither is universally better. Use Grid for two-dimensional layouts and Flexbox for one-dimensional alignment.
What does 1fr include exactly?
It represents a fraction of the remaining free space after fixed-size tracks and gaps are accounted for.
Why are my items not forming multiple rows?
Check container width, track definitions, and whether your pattern allows responsive wrapping (for example with auto-fit and minmax).
Should I always use auto-fit?
Not always. Use explicit track counts when design requires strict column numbers at specific breakpoints.
Does Grid replace media queries completely?
No. Grid reduces many breakpoint needs, but media queries are still important for broader responsive behavior and typography adjustments.