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 count
  • auto-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;
}
.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:

  1. Inspect grid container
  2. Elements panel shows "Grid" badge
  3. Click badge to toggle grid overlay
  4. 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:

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.