3.5: Grid Layout
Learn CSS Grid for creating complex two-dimensional layouts with precise control over rows and columns. Build responsive page structures using grid templates, areas, and alignment properties.
1. Introduction to CSS Grid
CSS Grid is a two-dimensional layout system for rows and columns.
Grid vs Flexbox
Flexbox (1D):
────────────────────
[Item] [Item] [Item] ← Single direction (row or column)
CSS Grid (2D):
┌──────┬──────┬──────┐
│ Item │ Item │ Item │ ← Rows AND columns
├──────┼──────┼──────┤
│ Item │ Item │ Item │
└──────┴──────┴──────┘
When to use:
- Flexbox: Navigation, cards in a row, centering
- Grid: Page layouts, complex 2D grids, magazine-style designs
2. Creating a Grid Container
Basic Grid Setup
.container {
display: grid;
}
/* Inline grid (rare) */
.container {
display: inline-grid;
}
HTML:
<div class="grid">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
</div>
3. Grid Template Columns & Rows
Define the grid structure.
Grid Template Columns
/* Fixed columns */
.grid {
display: grid;
grid-template-columns: 200px 200px 200px;
}
/* Percentage columns */
.grid {
grid-template-columns: 33.333% 33.333% 33.333%;
}
/* Flexible columns (fr units) */
.grid {
grid-template-columns: 1fr 1fr 1fr; /* Equal thirds */
}
/* Mixed units */
.grid {
grid-template-columns: 200px 1fr 2fr;
/* Fixed 200px, remaining space split 1:2 */
}
Grid Template Rows
.grid {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: 100px 200px; /* First 2 rows explicit */
}
/* Auto rows (implicit rows) */
.grid {
grid-auto-rows: 150px; /* All implicit rows 150px */
}
Repeat Function
/* Instead of: 1fr 1fr 1fr 1fr */
.grid {
grid-template-columns: repeat(4, 1fr);
}
/* Mixed repeat */
.grid {
grid-template-columns: 200px repeat(3, 1fr) 100px;
}
/* Multiple values in repeat */
.grid {
grid-template-columns: repeat(2, 1fr 2fr);
/* Results in: 1fr 2fr 1fr 2fr */
}
Minmax Function
/* Flexible sizing with constraints */
.grid {
grid-template-columns: repeat(3, minmax(200px, 1fr));
/* Min 200px, max 1fr */
}
/* Content-based sizing */
.grid {
grid-template-columns: minmax(min-content, 300px) 1fr;
}
4. Gap (Grid Spacing)
Space between grid items.
/* All gaps */
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20px;
}
/* Row and column gaps */
.grid {
row-gap: 20px;
column-gap: 30px;
}
/* Shorthand */
.grid {
gap: 20px 30px; /* row-gap column-gap */
}
5. Grid Lines & Positioning
Grid lines number from 1 (start) to n+1 (end).
Understanding Grid Lines
1 2 3 4
│ │ │ │
1 ──┼───────┼───────┼───────┼──
│ A │ B │ C │
2 ──┼───────┼───────┼───────┼──
│ D │ E │ F │
3 ──┼───────┼───────┼───────┼──
Positioning Items
/* Span columns 1-3, rows 1-2 */
.item-a {
grid-column-start: 1;
grid-column-end: 3;
grid-row-start: 1;
grid-row-end: 2;
}
/* Shorthand */
.item-a {
grid-column: 1 / 3; /* start / end */
grid-row: 1 / 2;
}
/* Span syntax */
.item-b {
grid-column: 1 / span 2; /* Start at 1, span 2 columns */
grid-row: 2 / span 1; /* Start at 2, span 1 row */
}
/* Even shorter */
.item-c {
grid-area: 1 / 1 / 2 / 3;
/* row-start / col-start / row-end / col-end */
}
Negative Line Numbers
/* -1 is last line */
.item {
grid-column: 1 / -1; /* First to last column (full width) */
}
6. Grid Template Areas
Named grid areas for intuitive layouts.
Defining Grid Areas
.grid {
display: grid;
grid-template-columns: 200px 1fr 200px;
grid-template-rows: auto 1fr auto;
grid-template-areas:
"header header header"
"sidebar content ads"
"footer footer footer";
gap: 20px;
min-height: 100vh;
}
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.content { grid-area: content; }
.ads { grid-area: ads; }
.footer { grid-area: footer; }
HTML:
<div class="grid">
<header class="header">Header</header>
<aside class="sidebar">Sidebar</aside>
<main class="content">Content</main>
<aside class="ads">Ads</aside>
<footer class="footer">Footer</footer>
</div>
Empty Cells
.grid {
grid-template-areas:
"header header header"
"sidebar content ." /* . = empty cell */
"footer footer footer";
}
7. Auto-Fit & Auto-Fill
Responsive grids without media queries.
Auto-Fill
Creates as many tracks as fit, even if empty.
.grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
gap: 20px;
}
/* Creates: 250px 250px 250px (even if last is empty) */
Auto-Fit
Creates tracks and collapses empty ones.
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 20px;
}
/* Creates: 250px 250px 250px (expands to fill if fewer items) */
Difference: Auto-Fill vs Auto-Fit
auto-fill (3 items in 4-column grid):
[Item 1] [Item 2] [Item 3] [empty]
auto-fit (3 items in 4-column grid):
[ Item 1 ] [ Item 2 ] [ Item 3 ] ← Expands to fill
Use case:
auto-fill: Want consistent column countauto-fit: Want items to grow when fewer
8. Grid Alignment
Justify Items (Horizontal Alignment)
Aligns items within their grid cells (horizontal).
.grid {
justify-items: start; /* Default */
justify-items: end;
justify-items: center;
justify-items: stretch; /* Fill cell width */
}
/* Individual item */
.item {
justify-self: center;
}
Align Items (Vertical Alignment)
Aligns items within their grid cells (vertical).
.grid {
align-items: start;
align-items: end;
align-items: center;
align-items: stretch; /* Default */
}
/* Individual item */
.item {
align-self: center;
}
Place Items (Shorthand)
/* align-items justify-items */
.grid {
place-items: center center;
place-items: start end;
}
Justify Content (Grid Alignment)
Aligns entire grid within container (horizontal).
.grid {
width: 800px;
grid-template-columns: repeat(3, 200px);
justify-content: start;
justify-content: end;
justify-content: center;
justify-content: space-between;
justify-content: space-around;
justify-content: space-evenly;
}
Align Content (Grid Alignment)
Aligns entire grid within container (vertical).
.grid {
height: 600px;
align-content: start;
align-content: end;
align-content: center;
align-content: space-between;
}
9. Common Grid Patterns
Holy Grail Layout
.page {
display: grid;
grid-template-columns: 200px 1fr 250px;
grid-template-rows: auto 1fr auto;
grid-template-areas:
"header header header"
"nav content aside"
"footer footer footer";
gap: 20px;
min-height: 100vh;
}
.header { grid-area: header; }
.nav { grid-area: nav; }
.content { grid-area: content; }
.aside { grid-area: aside; }
.footer { grid-area: footer; }
Card Grid (Responsive)
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 24px;
}
Magazine Layout
.magazine {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: repeat(3, 200px);
gap: 16px;
}
.featured {
grid-column: 1 / 3;
grid-row: 1 / 3;
}
.article-1 {
grid-column: 3 / 5;
}
.article-2 {
grid-column: 3 / 4;
}
.article-3 {
grid-column: 4 / 5;
}
Photo Gallery
.gallery {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
grid-auto-rows: 200px;
gap: 10px;
}
.gallery-item {
overflow: hidden;
}
.gallery-item img {
width: 100%;
height: 100%;
object-fit: cover;
}
/* Spanning items */
.gallery-item.wide {
grid-column: span 2;
}
.gallery-item.tall {
grid-row: span 2;
}
Dashboard Layout
.dashboard {
display: grid;
grid-template-columns: repeat(12, 1fr);
grid-auto-rows: minmax(100px, auto);
gap: 16px;
}
.widget-large {
grid-column: span 8;
grid-row: span 2;
}
.widget-medium {
grid-column: span 4;
}
.widget-small {
grid-column: span 3;
}
10. Responsive Grid
Mobile-First Grid
/* Mobile: Single column */
.grid {
display: grid;
grid-template-columns: 1fr;
gap: 20px;
}
/* Tablet: 2 columns */
@media (min-width: 768px) {
.grid {
grid-template-columns: repeat(2, 1fr);
}
}
/* Desktop: 3 columns */
@media (min-width: 1024px) {
.grid {
grid-template-columns: repeat(3, 1fr);
}
}
Responsive with Auto-Fit
/* No media queries needed! */
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 20px;
}
Responsive Grid Areas
/* Mobile */
.page {
display: grid;
grid-template-areas:
"header"
"content"
"sidebar"
"footer";
}
/* Desktop */
@media (min-width: 768px) {
.page {
grid-template-columns: 200px 1fr;
grid-template-areas:
"header header"
"sidebar content"
"footer footer";
}
}
11. Grid + Flexbox
Combine for powerful layouts.
Grid for Layout, Flexbox for Components
/* Grid for page structure */
.page {
display: grid;
grid-template-columns: 250px 1fr;
gap: 20px;
}
/* Flexbox for card internals */
.card {
display: flex;
flex-direction: column;
gap: 16px;
}
.card-footer {
margin-top: auto; /* Push to bottom with Flexbox */
}
Nested Grids
/* Outer grid */
.page {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 20px;
}
/* Inner grid */
.section {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 10px;
}
12. Advanced Grid Features
Dense Packing
.grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-auto-flow: dense; /* Fill gaps */
}
Implicit Grids
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
/* Auto-create rows as needed */
grid-auto-rows: 150px;
/* Auto-create columns as needed */
grid-auto-columns: 200px;
/* Flow direction */
grid-auto-flow: row; /* Default */
grid-auto-flow: column; /* Create columns */
}
Subgrid (Modern Feature)
.parent {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20px;
}
.child {
display: grid;
grid-column: span 2;
grid-template-columns: subgrid; /* Inherit parent columns */
}
13. Debugging Grid
Browser DevTools
Chrome/Edge/Firefox:
- Inspect grid container
- Elements panel shows "Grid" badge
- Click badge to toggle grid overlay
- Shows grid lines, gaps, and areas
Grid overlay displays:
- Grid lines with numbers
- Grid gaps
- Grid areas (named regions)
- Track sizes
Common Issues
Issue: Items overlapping
/* Explicit positioning conflicts */
.item-1, .item-2 {
grid-area: 1 / 1 / 2 / 2; /* Both in same cell */
}
/* Solution: Use different areas or auto-placement */
Issue: Grid not full width
/* Grid items have implicit width: auto */
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
width: 100%; /* Ensure full width */
}
14. Practical Exercises
Exercise 3.5.1: Holy Grail Layout
Create a page with:
- Fixed header (100px)
- 200px left sidebar
- Flexible main content
- 250px right sidebar
- Fixed footer (80px)
Exercise 3.5.2: Responsive Card Grid
Build a card grid that:
- Shows 1 column on mobile
- Shows 2 columns on tablet (768px+)
- Shows 4 columns on desktop (1200px+)
- Uses gap: 24px
Exercise 3.5.3: Magazine Layout
Create a magazine-style grid:
- Featured article spans 2 columns, 2 rows
- 4 smaller articles
- All responsive with auto-fit
Exercise 3.5.4: Dashboard
Build a dashboard with:
- 12-column grid
- Widgets of various sizes
- Large widget: 8 columns, 2 rows
- Medium widget: 4 columns, 1 row
- Small widget: 3 columns, 1 row
15. Knowledge Check
Question 1: What's the difference between 1fr and auto?
Show answer
1fr divides available space proportionally. auto sizes based on content.Question 2: What's the difference between auto-fit and auto-fill?
Show answer
auto-fill creates tracks even if empty. auto-fit collapses empty tracks and expands items to fill.Question 3: How do you make an item span the full width of a grid?
Show answer
grid-column: 1 / -1; (from first to last line)Question 4: What does grid-template-areas do?
Show answer
Defines named grid areas for intuitive layout, allowing you to assign items to regions by name.Question 5: When should you use Grid vs Flexbox?
Show answer
Grid for 2D layouts (rows AND columns). Flexbox for 1D layouts (single row or column).Question 6: What's the purpose of minmax()?
Show answer
Sets minimum and maximum size for grid tracks. E.g., minmax(200px, 1fr) = min 200px, max 1fr.16. Common Mistakes to Avoid
❌ Not Using fr Units
/* Bad - fixed widths */
.grid {
grid-template-columns: 300px 300px 300px;
}
/* Good - flexible widths */
.grid {
grid-template-columns: repeat(3, 1fr);
}
❌ Forgetting Gap
/* Bad - no spacing */
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
}
/* Good - with gap */
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 24px;
}
❌ Using Grid for Simple Layouts
/* Overkill for simple row */
.nav {
display: grid;
grid-template-columns: repeat(4, auto);
}
/* Better - use Flexbox */
.nav {
display: flex;
gap: 20px;
}
17. Key Takeaways
✅ CSS Grid - Two-dimensional layout system (rows and columns) ✅ fr unit - Flexible fraction of available space ✅ repeat() - Shorthand for repeating track sizes ✅ minmax() - Flexible sizing with constraints ✅ auto-fit/auto-fill - Responsive grids without media queries ✅ grid-template-areas - Named areas for intuitive layouts ✅ gap - Spacing between grid items ✅ Grid lines - Number from 1 to n+1, -1 is last line ✅ Alignment - justify/align for items and content ✅ Grid + Flexbox - Combine for powerful layouts
18. Further Resources
Official Documentation:
Interactive Learning:
- Grid Garden - Game to learn Grid
- Grid by Example - Rachel Andrew's examples
Tools:
Next Steps
Fantastic! You've mastered CSS Grid for complex two-dimensional layouts.
In Lesson 3.6: Responsive Design & Media Queries, you'll learn to make layouts adapt to different screen sizes and devices.