Stage 2: Frontend Fundamentals

CSS · Lesson 06

Grid

Two-dimensional layout with grid-template, fr units, spanning and named areas.

CSS2 min readFree lesson

CSS Grid is a powerful CSS technique for creating two-dimensional layouts (horizontal and vertical at the same time).
It is a better fit than Flexbox when you build magazine layouts, dashboards, and complex page structures.


1. Basic Grid Setup

.container {
  display: grid;

  /* Define columns */
  grid-template-columns: 200px 1fr 1fr; /* fixed 200px + two equal columns */
  grid-template-columns: repeat(3, 1fr); /* three equal columns */
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); /* responsive */

  /* Define rows */
  grid-template-rows: auto 1fr auto; /* top / middle / bottom */
  grid-template-rows: 80px 1fr 60px;

  /* Gaps */
  gap: 20px;
  row-gap: 16px;
  column-gap: 24px;
}

2. The fr Unit

fr represents a share of the remaining space.

.grid {
  display: grid;
  grid-template-columns: 1fr 2fr 1fr;
  /* Split the whole into 4 parts: first column 1/4, second column 2/4 (half), third column 1/4 */
}

3. Placing Items (grid-column, grid-row)

/* Specify which line an item starts and ends on */
.item {
  grid-column: 1 / 3;    /* starts at line 1, ends at line 3 (spans 2 columns) */
  grid-column: 1 / -1;   /* first line to last line (full width) */
  grid-column: span 2;   /* span 2 columns (from the current position) */

  grid-row: 1 / 3;       /* spans 2 rows */
  grid-row: span 2;
}

4. grid-template-areas

This defines a layout visually by name.

.container {
  display: grid;
  grid-template-columns: 200px 1fr;
  grid-template-rows: 60px 1fr 40px;
  grid-template-areas:
    "header  header"
    "sidebar main"
    "footer  footer";
}

.header  { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main    { grid-area: main; }
.footer  { grid-area: footer; }

5. auto-fill vs auto-fit

/* auto-fill: creates as many columns as possible, empty columns may remain */
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));

/* auto-fit: fills columns to fit the items, empty columns collapse to 0 */
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));

6. Alignment

.container {
  justify-items: start | center | end | stretch;   /* horizontal alignment inside a cell */
  align-items: start | center | end | stretch;     /* vertical alignment inside a cell */
  justify-content: start | center | space-between; /* horizontal alignment of the whole grid */
  align-content: start | center | space-between;   /* vertical alignment of the whole grid */
}

.item {
  justify-self: center;  /* horizontally center only this item */
  align-self: end;       /* vertically align only this item to the end */
}

7. Flexbox vs Grid — How to Choose

Situation Recommendation
Aligning in only one direction (horizontal or vertical) Flexbox
Need to control both directions at once Grid
Items have irregular sizes Flexbox
A layout with defined rows and columns Grid
Navigation, button groups Flexbox
Whole-page layouts, dashboards Grid

In practice, a common pattern is to build the overall layout with Grid and implement the inner components with Flexbox.


Example Files

Open grid-layout.html in the examples/ folder to see the magazine layout.

Assignment

Read assignment.md and try building a dashboard layout.

Example files

Complete, runnable files used in this lesson. Copy them into your project and experiment.

grid-layout.htmlHTML
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>CSS Grid — Magazine Layout</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>

  <header class="page-header">
    <h1>CSS Grid Magazine Layout</h1>
    <p>A magazine-style layout built with grid-template-areas and grid-column/row span</p>
  </header>

  <div class="container">

    <!-- Magazine layout -->
    <div class="magazine-grid">

      <!-- Header banner: full width -->
      <div class="grid-item item-header">
        <div class="item-content">
          <span class="label">TODAY'S HEADLINE</span>
          <h2>Building the<br>Perfect Magazine Layout with CSS Grid</h2>
          <p>With the power of the grid system, even complex layouts become simple</p>
        </div>
      </div>

      <!-- Featured article: spans 2 rows -->
      <div class="grid-item item-featured">
        <div class="item-content">
          <span class="label">FEATURED</span>
          <h3>Flexbox vs Grid</h3>
          <p>We compare the strengths and weaknesses of the two layout systems and look at the criteria for choosing the right one. Grid is optimized for two-dimensional layouts, while Flexbox is optimized for one-dimensional layouts.</p>
          <p>In practice, using both techniques together is the most effective approach.</p>
        </div>
      </div>

      <!-- Small article 1 -->
      <div class="grid-item item-small-1">
        <div class="item-content">
          <span class="label">TIPS</span>
          <h3>What Is the fr Unit?</h3>
          <p>It is a Grid-only unit that divides the remaining space into proportions. It is essential for responsive layouts.</p>
        </div>
      </div>

      <!-- Small article 2 -->
      <div class="grid-item item-small-2">
        <div class="item-content">
          <span class="label">TIPS</span>
          <h3>Placing Elements by grid-area Name</h3>
          <p>Use the grid-template-areas property, which declares the layout visually.</p>
        </div>
      </div>

      <!-- Ad/sidebar -->
      <div class="grid-item item-ad">
        <div class="item-content ad-content">
          <span class="ad-label">AD</span>
          <p class="ad-title">CSS Master Class</p>
          <p class="ad-sub">A 30-day curriculum</p>
          <button class="ad-btn">Learn More</button>
        </div>
      </div>

      <!-- Footer banner -->
      <div class="grid-item item-footer">
        <div class="item-content footer-content">
          <span>Subscribe and get a new CSS tip every day</span>
          <button class="subscribe-btn">Subscribe for Free</button>
        </div>
      </div>

    </div>

    <!-- Grid property demos -->
    <section class="demo-section">
      <h2>Comparing grid-template-columns</h2>

      <div class="demo-block">
        <h3>repeat(3, 1fr) — split into 3 equal columns</h3>
        <div class="demo-grid grid-equal">
          <div class="demo-item">1fr</div>
          <div class="demo-item">1fr</div>
          <div class="demo-item">1fr</div>
        </div>
      </div>

      <div class="demo-block">
        <h3>200px 1fr 1fr — fixed + fluid</h3>
        <div class="demo-grid grid-mixed">
          <div class="demo-item">200px</div>
          <div class="demo-item">1fr</div>
          <div class="demo-item">1fr</div>
        </div>
      </div>

      <div class="demo-block">
        <h3>1fr 2fr 1fr — proportional split</h3>
        <div class="demo-grid grid-ratio">
          <div class="demo-item">1fr</div>
          <div class="demo-item">2fr</div>
          <div class="demo-item">1fr</div>
        </div>
      </div>

      <div class="demo-block">
        <h3>grid-column: span — merging columns</h3>
        <div class="demo-grid grid-span">
          <div class="demo-item span-2">span 2</div>
          <div class="demo-item">1fr</div>
          <div class="demo-item">1fr</div>
          <div class="demo-item span-3">span 3 (full width)</div>
        </div>
      </div>
    </section>

  </div>

  <footer class="main-footer">
    <p>CSS Grid Magazine Layout Example &copy; 2025</p>
  </footer>

</body>
</html>
style.cssCSS
/* =============================================
   CSS Grid Magazine Layout Example
   Lesson 06: grid-template / fr / grid-column / grid-row / grid-template-areas
   ============================================= */

* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

body {
  font-family: 'Segoe UI', Arial, sans-serif;
  background-color: #f5f6fa;
  color: #333;
  line-height: 1.6;
}

.page-header {
  background: linear-gradient(135deg, #2c3e50, #3498db);
  color: white;
  text-align: center;
  padding: 50px 20px;
}

.page-header h1 {
  font-size: 2rem;
  margin-bottom: 10px;
}

.page-header p {
  opacity: 0.85;
  font-size: 0.95rem;
}

.container {
  max-width: 1100px;
  margin: 0 auto;
  padding: 40px 20px;
}

/* =============================================
   Magazine layout: CSS Grid
   5 columns × automatic rows structure
   ============================================= */
.magazine-grid {
  display: grid;                              /* Grid container */
  grid-template-columns: repeat(4, 1fr);      /* Split into 4 equal columns */
  grid-template-rows: 200px 200px 60px;       /* Set row heights */
  gap: 16px;                                  /* Row/column gaps */

  /* Declare the visual layout with grid-template-areas */
  grid-template-areas:
    "header   header   header   header"    /* Row 1: header spans full width */
    "featured featured small1   ad"        /* Row 2: featured/small article/ad */
    "featured featured small2   ad"        /* Row 3: featured continues/small article/ad */
    "footer   footer   footer   footer";   /* Row 4: footer spans full width */

  grid-template-rows: 160px 140px 140px 60px;
  margin-bottom: 40px;
}

/* Common grid item style */
.grid-item {
  border-radius: 10px;
  overflow: hidden;
  position: relative;
}

.item-content {
  padding: 20px;
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: flex-end; /* Push content to the bottom */
}

.label {
  font-size: 0.7rem;
  font-weight: 800;
  letter-spacing: 2px;
  text-transform: uppercase;
  opacity: 0.8;
  margin-bottom: 8px;
  display: block;
}

/* =============================================
   Header: grid-area: header (full width)
   ============================================= */
.item-header {
  grid-area: header;      /* Connected to the grid-template-areas name */
  background: linear-gradient(135deg, #667eea, #764ba2);
  color: white;
}

.item-header h2 {
  font-size: 1.6rem;
  font-weight: 900;
  margin-bottom: 6px;
  line-height: 1.3;
}

.item-header p {
  font-size: 0.88rem;
  opacity: 0.85;
}

/* =============================================
   Featured article: grid-area: featured (spans 2 rows)
   ============================================= */
.item-featured {
  grid-area: featured;    /* Spans 2 rows (defined in the template) */
  background: linear-gradient(160deg, #0093e9, #80d0c7);
  color: white;
}

.item-featured .item-content {
  justify-content: flex-start;
  padding-top: 24px;
}

.item-featured h3 {
  font-size: 1.3rem;
  font-weight: 800;
  margin-bottom: 10px;
}

.item-featured p {
  font-size: 0.85rem;
  opacity: 0.9;
  line-height: 1.6;
  margin-bottom: 8px;
}

/* =============================================
   Small articles 1 and 2
   ============================================= */
.item-small-1 {
  grid-area: small1;
  background: linear-gradient(135deg, #f093fb, #f5576c);
  color: white;
}

.item-small-2 {
  grid-area: small2;
  background: linear-gradient(135deg, #43e97b, #38f9d7);
  color: white;
}

.item-small-1 h3,
.item-small-2 h3 {
  font-size: 1rem;
  font-weight: 700;
  margin-bottom: 8px;
}

.item-small-1 p,
.item-small-2 p {
  font-size: 0.82rem;
  opacity: 0.9;
}

/* =============================================
   Ad (spans 2 rows): grid-area: ad
   ============================================= */
.item-ad {
  grid-area: ad;
  background-color: #2c3e50;
  color: white;
}

.ad-content {
  justify-content: center;
  align-items: center;
  text-align: center;
  gap: 8px;
}

.ad-label {
  font-size: 0.65rem;
  background-color: #e74c3c;
  padding: 2px 8px;
  border-radius: 3px;
  width: fit-content;
  align-self: center;
}

.ad-title {
  font-size: 1rem;
  font-weight: 800;
  color: white;
}

.ad-sub {
  font-size: 0.8rem;
  color: #aab7b8;
  margin: 0;
}

.ad-btn {
  padding: 8px 16px;
  background-color: #3498db;
  color: white;
  border: none;
  border-radius: 6px;
  font-size: 0.82rem;
  font-weight: 700;
  cursor: pointer;
  margin-top: 4px;
}

/* =============================================
   Footer: grid-area: footer (full width)
   ============================================= */
.item-footer {
  grid-area: footer;
  background-color: #2c3e50;
  color: white;
}

.footer-content {
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
  padding: 0 24px;
  font-size: 0.88rem;
}

.subscribe-btn {
  padding: 8px 20px;
  background-color: #3498db;
  color: white;
  border: none;
  border-radius: 6px;
  font-weight: 700;
  cursor: pointer;
  font-size: 0.85rem;
  white-space: nowrap;
}

/* =============================================
   Grid property demo section
   ============================================= */
.demo-section {
  background: white;
  border-radius: 12px;
  padding: 28px;
  box-shadow: 0 2px 10px rgba(0,0,0,0.07);
}

.demo-section h2 {
  font-size: 1.2rem;
  color: #2c3e50;
  margin-bottom: 24px;
  padding-bottom: 10px;
  border-bottom: 2px solid #3498db;
}

.demo-block {
  margin-bottom: 24px;
}

.demo-block h3 {
  font-size: 0.9rem;
  color: #555;
  margin-bottom: 10px;
  font-family: 'Courier New', monospace;
}

/* Common demo grid */
.demo-grid {
  display: grid;         /* Grid container */
  gap: 8px;              /* Cell gaps */
  background-color: #f0f2f5;
  padding: 10px;
  border-radius: 6px;
}

.demo-item {
  background-color: #667eea;
  color: white;
  font-weight: 700;
  font-size: 0.82rem;
  padding: 14px 10px;
  border-radius: 6px;
  text-align: center;
}

/* Split into 3 equal columns */
.grid-equal {
  grid-template-columns: repeat(3, 1fr); /* 1fr 1fr 1fr */
}

/* Fixed + fluid */
.grid-mixed {
  grid-template-columns: 200px 1fr 1fr; /* Fixed 200px + 2 fluid columns */
}

/* Proportional split */
.grid-ratio {
  grid-template-columns: 1fr 2fr 1fr;   /* 1:2:1 ratio */
}

/* Merging columns (span) */
.grid-span {
  grid-template-columns: repeat(3, 1fr);
}

.span-2 {
  grid-column: span 2;           /* Spans 2 columns */
  background-color: #e74c3c;
}

.span-3 {
  grid-column: span 3;           /* Spans all 3 columns */
  background-color: #27ae60;
}

/* Footer */
.main-footer {
  background-color: #2c3e50;
  color: #aab7b8;
  text-align: center;
  padding: 24px;
  font-size: 0.85rem;
  margin-top: 40px;
}

Assignment

Assignment — Dashboard Layout

Goal

Use grid-template-areas to build a
dashboard layout made up of a sidebar + main area.


Requirements

Layout Structure

┌─────────────────────────────────────────┐
│                 header                  │ ← full width
├────────┬────────────────────────────────┤
│        │              main              │
│sidebar │   ┌────────┬────────┬───────┐  │
│        │   │ card1  │ card2  │ card3 │  │
│        │   └────────┴────────┴───────┘  │
│        │   ┌──────────────────────────┐ │
│        │   │        chart area        │ │
│        │   └──────────────────────────┘ │
├────────┴────────────────────────────────┤
│                 footer                  │ ← full width
└─────────────────────────────────────────┘

Using grid-template-areas (Required)

.dashboard {
  display: grid;
  grid-template-columns: 220px 1fr;    /* fixed sidebar + fluid main */
  grid-template-rows: 60px 1fr 50px;   /* header/main/footer */
  grid-template-areas:
    "header  header"
    "sidebar main"
    "footer  footer";
  min-height: 100vh;
}

Styles for Each Area

Area Style
header Logo + navigation (use Flexbox)
sidebar A menu list with 3–5 items
main Three stat cards + a large content area
footer A simple copyright notice

Inside the Main Area (Use Grid Again)

.stats-cards {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
}

Checklist

  • I declared the layout with grid-template-areas
  • I placed each element in its area with grid-area
  • The sidebar width is fixed (px) and the main area is fluid (fr)
  • I placed three cards inside the main area with Grid
  • I did not use inline CSS

Hint

/* Connect each element to a grid-area name */
.header  { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main    { grid-area: main; }
.footer  { grid-area: footer; }

If you are curious about the answer, refer to the solution/ folder.

Learn this lesson with a mentor

Work through the Build Your Homepage series on your own, or join a guided cohort at our Pitampura campus and online.

Call NowEnroll Now