CSS Grid: Build Any Layout
CSS Grid: Build Any Layout
CSS Grid is the most powerful layout system on the web. Where Flexbox is one-dimensional (row OR column), Grid is two-dimensional — it controls both rows and columns simultaneously, making it possible to build any layout you can imagine.
The Grid Mental Model
Think of Grid like a table — you define rows and columns, then place items into cells. But unlike tables, Grid is designed for layout and is incredibly flexible.
.container {
display: grid;
grid-template-columns: 200px 1fr 200px; /* 3 columns */
grid-template-rows: 80px 1fr 60px; /* 3 rows */
gap: 16px; /* Space between cells */
}
The fr unit is key — it means "fraction of remaining space". 1fr 2fr gives you a 1:2 ratio.
Defining Columns and Rows
/* Fixed widths */
grid-template-columns: 100px 200px 100px;
/* Percentage widths */
grid-template-columns: 25% 50% 25%;
/* Fractional units — responsive by default */
grid-template-columns: 1fr 2fr 1fr;
/* Mixed */
grid-template-columns: 200px 1fr; /* Fixed sidebar, flexible content */
/* repeat() — less repetition */
grid-template-columns: repeat(3, 1fr); /* 3 equal columns */
grid-template-columns: repeat(4, 200px); /* 4 fixed columns */
Responsive Grids Without Media Queries
The most useful CSS Grid technique: auto-fill/auto-fit with minmax()
/* Creates as many columns as fit, each at least 250px wide */
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
gap: 24px;
}
/* auto-fill: creates empty columns if there's space */
/* auto-fit: collapses empty columns (usually what you want) */
.card-grid {
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
}
This single rule creates a grid that:
- Shows 1 column on mobile
- Shows 2-3 columns on tablet
- Shows 4+ columns on desktop — with zero media queries.
Placing Items
Grid Line Placement
.item {
grid-column: 1 / 3; /* Start at line 1, end at line 3 (spans 2 columns) */
grid-row: 1 / 2; /* First row only */
}
/* Shorthand: grid-column-start / grid-column-end */
.header { grid-column: 1 / -1; } /* -1 = last line → spans full width */
.sidebar { grid-column: 1 / 2; grid-row: 2 / 4; } /* Spans 2 rows */
.main { grid-column: 2 / -1; grid-row: 2 / 3; }
span keyword
.feature-card {
grid-column: span 2; /* Spans 2 columns from its current position */
grid-row: span 2; /* Spans 2 rows */
}
Grid Template Areas — The Visual Way
The most readable approach for complex layouts:
.page {
display: grid;
grid-template-columns: 220px 1fr;
grid-template-rows: 70px 1fr 60px;
grid-template-areas:
"header header"
"sidebar main "
"footer footer";
gap: 0;
min-height: 100vh;
}
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main { grid-area: main; }
.footer { grid-area: footer; }
This makes the layout visually obvious in your CSS. The ASCII art in grid-template-areas directly shows what your page looks like.
Alignment
/* Align all items within the grid */
.container {
justify-items: start | center | end | stretch; /* Along row axis */
align-items: start | center | end | stretch; /* Along column axis */
place-items: center; /* Shorthand for both */
}
/* Align the entire grid within its container */
.container {
justify-content: start | center | end | space-between | space-around;
align-content: start | center | end | space-between;
}
/* Override alignment for a single item */
.special-item {
justify-self: center;
align-self: end;
place-self: center end; /* Shorthand */
}
Real-World Layout Examples
Classic Blog Layout
<div class="blog-layout">
<header class="blog-header">Header</header>
<main class="blog-main">Article Content</main>
<aside class="blog-sidebar">Sidebar</aside>
<footer class="blog-footer">Footer</footer>
</div>
.blog-layout {
display: grid;
grid-template-columns: 1fr 300px;
grid-template-rows: auto 1fr auto;
grid-template-areas:
"header header"
"main sidebar"
"footer footer";
gap: 24px;
max-width: 1200px;
margin: 0 auto;
padding: 20px;
min-height: 100vh;
}
.blog-header { grid-area: header; }
.blog-main { grid-area: main; }
.blog-sidebar{ grid-area: sidebar; }
.blog-footer { grid-area: footer; }
/* Responsive: stack on mobile */
@media (max-width: 768px) {
.blog-layout {
grid-template-columns: 1fr;
grid-template-areas:
"header"
"main"
"sidebar"
"footer";
}
}
Product Card Grid
.product-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 32px;
padding: 40px 20px;
}
/* Feature one card: spans 2 columns */
.product-card.featured {
grid-column: span 2;
}
@media (max-width: 600px) {
.product-card.featured {
grid-column: span 1;
}
}
Dashboard Layout
.dashboard {
display: grid;
grid-template-columns: 250px 1fr 1fr;
grid-template-rows: 64px repeat(3, 1fr);
grid-template-areas:
"nav header header"
"nav stats stats "
"nav chart table "
"nav chart table ";
height: 100vh;
gap: 0;
}
Grid vs Flexbox: When to Use Which
| Use Grid | Use Flexbox |
|---|---|
| Two-dimensional layout (rows AND columns) | One-dimensional layout (row OR column) |
| Overall page layout | Component-level layout |
| Precise item placement | Dynamic content flow |
| CSS art / magazine layouts | Navigation bars |
grid-template-areas for visual clarity | Card content alignment |
Most projects use both: Grid for the page structure, Flexbox inside components.
Next lesson: Responsive Design & Media Queries — making layouts that work on every screen.
Get this course's notes on Telegram!
Free cheat sheets, summaries & practice exercises