Learn CSS in 10 DaysDay 7: CSS Grid
Chapter 7Learn CSS in 10 Days

Day 7: CSS Grid

What You Will Learn Today

  • The fundamentals of CSS Grid
  • Grid container properties
  • Grid item placement
  • Template areas for visual layouts
  • Auto-placement with auto-fill and auto-fit
  • When to use Flexbox vs. Grid

What is CSS Grid?

CSS Grid is a two-dimensional layout system. Unlike Flexbox, which works along a single axis, Grid lets you control both rows and columns at the same time.

flowchart LR
    subgraph Compare["Flexbox vs Grid"]
        Flex["Flexbox<br>1-dimensional<br>Row OR Column"]
        Grid["Grid<br>2-dimensional<br>Rows AND Columns"]
    end
    style Flex fill:#3b82f6,color:#fff
    style Grid fill:#22c55e,color:#fff
.container {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    gap: 16px;
}

Grid Basics

grid-template-columns / grid-template-rows

Define the structure of your grid by specifying column and row sizes.

/* Three equal columns */
.grid-3 {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
}

/* Using the repeat() function */
.grid-3 {
    grid-template-columns: repeat(3, 1fr);
}

/* Fixed sidebar + flexible content */
.sidebar-layout {
    grid-template-columns: 250px 1fr;
}

/* Defining rows */
.grid {
    grid-template-rows: 80px 1fr 60px;
}

The fr Unit

The fr (fraction) unit distributes remaining space proportionally.

/* 1:2:1 ratio */
grid-template-columns: 1fr 2fr 1fr;

/* 200px fixed + remaining split equally */
grid-template-columns: 200px 1fr 1fr;
Value Description
1fr One fraction of the remaining space
200px Fixed 200px
auto Sized to fit the content
minmax(200px, 1fr) At least 200px, up to 1fr

gap (Spacing)

.grid {
    gap: 16px;            /* Both row and column gap */
    gap: 16px 24px;       /* Row gap, column gap */
    row-gap: 16px;
    column-gap: 24px;
}

Item Placement

Placing Items by Line Numbers

Grid lines are numbered starting at 1. You can place items by referencing these line numbers.

.item {
    grid-column: 1 / 3;    /* Column line 1 to 3 (spans 2 columns) */
    grid-row: 1 / 2;       /* Row line 1 to 2 (spans 1 row) */
}

/* Using span */
.item-wide {
    grid-column: span 2;   /* Span 2 columns */
}

.item-tall {
    grid-row: span 3;      /* Span 3 rows */
}
flowchart TB
    subgraph GridLines["Grid Line Numbers"]
        L["Columns: 1 | 2 | 3 | 4<br>Row: 1<br>──────<br>Row: 2<br>──────<br>Row: 3"]
    end
    style L fill:#3b82f6,color:#fff

grid-template-areas

Name regions of your grid and arrange them visually, like ASCII art.

.layout {
    display: grid;
    grid-template-areas:
        "header  header  header"
        "sidebar content content"
        "footer  footer  footer";
    grid-template-columns: 250px 1fr 1fr;
    grid-template-rows: 80px 1fr 60px;
    min-height: 100vh;
    gap: 0;
}

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

Key insight: grid-template-areas lets you visually define your layout right in the CSS. It makes the structure immediately obvious to anyone reading the code.


Auto-Placement

auto-fill and auto-fit

These keywords let the browser decide how many columns to create based on available space.

/* auto-fill: create as many columns as fit (empty tracks preserved) */
.grid-auto {
    grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
}

/* auto-fit: create as many columns as fit (empty tracks collapse) */
.grid-auto-fit {
    grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
}
Value Description
auto-fill Creates as many tracks as fit; empty tracks remain
auto-fit Creates as many tracks as fit; empty tracks collapse to zero

Best practice: For responsive card grids, repeat(auto-fit, minmax(250px, 1fr)) is the go-to pattern. It creates a responsive grid without any media queries.


Alignment Properties

Container-Level Alignment

.grid {
    justify-items: center;    /* Horizontal alignment within cells */
    align-items: center;      /* Vertical alignment within cells */
    place-items: center;      /* Shorthand for both */

    justify-content: center;  /* Horizontal alignment of the entire grid */
    align-content: center;    /* Vertical alignment of the entire grid */
    place-content: center;    /* Shorthand for both */
}

Item-Level Alignment

.item {
    justify-self: end;     /* Horizontal alignment of this item */
    align-self: center;    /* Vertical alignment of this item */
    place-self: center end;
}

Flexbox vs. Grid: Choosing the Right Tool

Scenario Recommended
Single-row navigation Flexbox
Cards in a row Flexbox or Grid
Full page layout Grid
Two-dimensional grid layout Grid
Centering an element Either works
Content determines the size Flexbox
You need explicit column/row control Grid
flowchart TB
    Q1{"Two-dimensional<br>layout?"}
    Q2{"Content determines<br>sizing?"}
    Grid["CSS Grid"]
    Flex["Flexbox"]
    Q1 -->|"Yes"| Grid
    Q1 -->|"No"| Q2
    Q2 -->|"Yes"| Flex
    Q2 -->|"No"| Grid
    style Grid fill:#22c55e,color:#fff
    style Flex fill:#3b82f6,color:#fff

Practice: Dashboard Layout

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

body {
    font-family: system-ui, sans-serif;
    color: #1e293b;
}

/* Full page layout */
.dashboard {
    display: grid;
    grid-template-areas:
        "sidebar header"
        "sidebar main";
    grid-template-columns: 250px 1fr;
    grid-template-rows: 64px 1fr;
    min-height: 100vh;
}

.header {
    grid-area: header;
    background: white;
    border-bottom: 1px solid #e2e8f0;
    display: flex;
    align-items: center;
    padding: 0 24px;
}

.sidebar {
    grid-area: sidebar;
    background: #1e293b;
    color: white;
    padding: 24px;
}

.main {
    grid-area: main;
    background: #f8fafc;
    padding: 24px;
}

/* Stats card grid */
.stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: 16px;
    margin-bottom: 24px;
}

.stat-card {
    background: white;
    padding: 24px;
    border-radius: 8px;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}

.stat-card h3 {
    font-size: 0.875rem;
    color: #64748b;
    margin-bottom: 8px;
}

.stat-card .number {
    font-size: 2rem;
    font-weight: 700;
}

/* Content area grid */
.content-grid {
    display: grid;
    grid-template-columns: 2fr 1fr;
    gap: 24px;
}

.panel {
    background: white;
    padding: 24px;
    border-radius: 8px;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}

Summary

Property Applies To Description
display: grid Container Enables Grid layout
grid-template-columns Container Defines column tracks
grid-template-rows Container Defines row tracks
grid-template-areas Container Names regions for placement
gap Container Spacing between cells
grid-column / grid-row Item Placement by line numbers
grid-area Item Placement by named area
fr Value Distributes remaining space

Key Takeaways

  1. The fr unit provides flexible space distribution
  2. grid-template-areas makes layouts visually self-documenting
  3. auto-fit + minmax() creates responsive grids without media queries
  4. Know when to choose Flexbox vs. Grid for the task at hand

Exercises

Exercise 1: Basics

Create a three-column card grid using CSS Grid.

Exercise 2: Intermediate

Use grid-template-areas to build a layout with header, sidebar, main content, and footer.

Challenge

Build a fully responsive grid using auto-fit and minmax() that adjusts its column count based on viewport width -- without any media queries.


References


Next up: In Day 8, you will learn about Responsive Design -- how to make your layouts adapt beautifully to any screen size using media queries and the mobile-first approach.