LearnContact
Lesson 1926 min read

CSS Grid

Learn how CSS Grid creates powerful two-dimensional layouts using rows, columns, tracks, gaps, placement, spanning, template areas, alignment, auto-fit, minmax, and responsive design.

Introduction

In the previous lesson, you learned CSS Flexbox and how it creates flexible one-dimensional layouts using rows or columns.

Now you will learn CSS Grid, a powerful two-dimensional layout system designed to control rows and columns together.

CSS Grid makes it easier to create page layouts, dashboards, galleries, card systems, application interfaces, responsive grids, and complex arrangements without relying on floats or complicated positioning.

Create Parent Container
Enable Grid
Define Columns
Define Rows
Add Gaps
Place Grid Items
Span Rows or Columns
Align Content
Create Responsive Layout
Grid Is a Two-Dimensional Layout System

CSS Grid can control rows and columns at the same time, making it ideal for layouts where both horizontal and vertical structure matter.

What is CSS Grid?

CSS Grid is a two-dimensional layout system that divides a container into rows and columns.

Elements can then be placed into grid cells, moved between grid lines, stretched across multiple rows or columns, and aligned within the available space.

Basic Grid
.container {
    display: grid;

    grid-template-columns: 1fr 1fr 1fr;
}
Grid Structure
┌────────────┬────────────┬────────────┐
│            │            │            │
│   Item 1   │   Item 2   │   Item 3   │
│            │            │            │
├────────────┼────────────┼────────────┤
│            │            │            │
│   Item 4   │   Item 5   │   Item 6   │
│            │            │            │
└────────────┴────────────┴────────────┘

       Columns + Rows = Grid
One Property Creates the Grid

Adding display: grid to a parent creates a grid formatting context. You can then define its rows and columns.

Why Do We Need Grid?

Many website layouts require control in two directions at the same time.

For example, a dashboard may have a sidebar, header, main content area, footer, and cards that span different numbers of rows and columns.

Columns

Define and control multiple horizontal tracks.

Rows

Define and control multiple vertical tracks.

Spanning

Allow items to occupy multiple rows or columns.

Precise Placement

Place elements using grid lines or named areas.

Responsive Layouts

Create flexible grids that adapt automatically.

Complex Structure

Build layouts that are difficult with normal document flow.

Older Layout Techniques

  • Floats require clearing.
  • Column calculations are manual.
  • Complex layouts need many wrappers.
  • Two-dimensional alignment is difficult.

CSS Grid

  • Rows and columns are built in.
  • Flexible fractions simplify sizing.
  • Items can span multiple tracks.
  • Alignment is built into the layout system.

Real-World Analogy

Imagine a chessboard.

The board is the grid container. The horizontal divisions create rows, the vertical divisions create columns, and each square is a grid cell.

Chessboard Analogy
Grid Container

       Column 1    Column 2    Column 3
          │           │           │
          ▼           ▼           ▼

      ┌───────────┬───────────┬───────────┐
Row 1 │   Cell    │   Cell    │   Cell    │
      ├───────────┼───────────┼───────────┤
Row 2 │   Cell    │   Cell    │   Cell    │
      ├───────────┼───────────┼───────────┤
Row 3 │   Cell    │   Cell    │   Cell    │
      └───────────┴───────────┴───────────┘

A grid item can occupy one cell or stretch across several cells, similar to placing a large game piece across multiple squares.

Chessboard ConceptCSS Grid Concept
BoardGrid container
Game pieceGrid item
Vertical divisionColumn
Horizontal divisionRow
SquareGrid cell
Border between squaresGrid line
Several connected squaresGrid area

Grid Terminology

Grid Container

The parent element where display: grid or inline-grid is applied.

Grid Item

A direct child of the grid container.

│ Grid Line

A horizontal or vertical dividing line in the grid.

Grid Track

The space between two adjacent grid lines.

Grid Cell

The smallest area between one row and one column.

Grid Area

A rectangular region containing one or more grid cells.

Grid Container & Items

HTML Structure
<div class="container">
    <div class="item">Item 1</div>
    <div class="item">Item 2</div>
    <div class="item">Item 3</div>
</div>
Grid Container
.container {
    display: grid;
}
Grid Relationship
Grid Container
┌──────────────────────────────────────┐
│                                      │
│  ┌────────┐ ┌────────┐ ┌────────┐    │
│  │ Item 1 │ │ Item 2 │ │ Item 3 │    │
│  └────────┘ └────────┘ └────────┘    │
│                                      │
└──────────────────────────────────────┘

.container = Grid Container

.item = Direct Grid Items
Only Direct Children Become Grid Items

Like Flexbox, only direct children of a grid container become grid items. Nested descendants do not automatically participate in the parent grid.

Grid Lines, Tracks & Cells

A grid is formed by horizontal and vertical grid lines.

The space between two adjacent lines is called a track. A column is a vertical track, while a row is a horizontal track.

Grid Anatomy
          Line 1      Line 2      Line 3      Line 4
             │           │           │           │
             ▼           ▼           ▼           ▼

Line 1 ──►  ┌───────────┬───────────┬───────────┐
            │   Cell    │   Cell    │   Cell    │
Line 2 ──►  ├───────────┼───────────┼───────────┤
            │   Cell    │   Cell    │   Cell    │
Line 3 ──►  └───────────┴───────────┴───────────┘

             ◄───────── Column Track ─────────►

            One horizontal strip = Row Track
TermMeaning
Grid lineBoundary between tracks
Grid trackSpace between adjacent grid lines
ColumnVertical grid track
RowHorizontal grid track
Grid cellIntersection of one row and one column
Grid areaRectangular group of one or more cells

Creating a Grid Container

Block-Level Grid
.container {
    display: grid;
}
Inline-Level Grid
.container {
    display: inline-grid;
}
ValueContainer Behavior
gridCreates a block-level grid container
inline-gridCreates an inline-level grid container

Example 1: Basic Grid

HTML
<div class="container">
    <div class="item">HTML</div>
    <div class="item">CSS</div>
    <div class="item">JavaScript</div>
    <div class="item">React</div>
    <div class="item">Next.js</div>
    <div class="item">Node.js</div>
</div>
CSS
.container {
    display: grid;

    grid-template-columns: 1fr 1fr 1fr;

    gap: 12px;
}

.item {
    padding: 24px;

    background: #6c5ce7;
    color: white;

    text-align: center;

    border-radius: 10px;
}

grid-template-columns

The grid-template-columns property defines the number and size of columns in the explicit grid.

Three Columns
.container {
    display: grid;

    grid-template-columns: 200px 300px 200px;
}
Column Tracks
       200px         300px         200px

┌──────────────┬────────────────────┬──────────────┐
│              │                    │              │
│   Column 1   │      Column 2      │   Column 3   │
│              │                    │              │
└──────────────┴────────────────────┴──────────────┘

Fixed-Size Columns

Columns can use fixed units such as pixels.

Fixed Columns
.container {
    display: grid;

    grid-template-columns: 200px 300px 200px;
}
Fixed Columns Can Overflow

If the total fixed column width is larger than the container, the grid may overflow on smaller screens.

Percentage Columns

Percentage Columns
.container {
    display: grid;

    grid-template-columns: 25% 50% 25%;
}

Percentage columns are calculated from the grid container width.

Remember the Gap

Percentages plus grid gaps can exceed the container width because the gap occupies additional space.

The fr Unit

The fr unit represents a fraction of the available space in the grid container.

Equal Fractions
.container {
    grid-template-columns: 1fr 1fr 1fr;
}
Equal Fraction Distribution
Available Space

┌──────────────┬──────────────┬──────────────┐
│              │              │              │
│    1fr       │     1fr      │     1fr      │
│              │              │              │
└──────────────┴──────────────┴──────────────┘

Each column receives one equal fraction.
Different Fractions
.container {
    grid-template-columns: 1fr 2fr 1fr;
}
Fraction Ratio
Total Fraction Units = 4

Column 1 = 1fr = 1/4
Column 2 = 2fr = 2/4
Column 3 = 1fr = 1/4

┌──────────┬────────────────────┬──────────┐
│   1fr    │        2fr         │   1fr    │
└──────────┴────────────────────┴──────────┘
Use fr for Flexible Grid Tracks

The fr unit is usually more convenient than percentages when you want columns to share the remaining available space.

Example 2: Equal Columns

HTML
<div class="features">
    <div class="feature">Fast</div>
    <div class="feature">Responsive</div>
    <div class="feature">Modern</div>
</div>
CSS
.features {
    display: grid;

    grid-template-columns: 1fr 1fr 1fr;

    gap: 20px;
}

.feature {
    padding: 30px;

    background: #6c5ce7;
    color: white;

    text-align: center;

    border-radius: 12px;
}

Mixed Column Sizes

Grid tracks can combine fixed, flexible, percentage, and automatic sizes.

Fixed Sidebar and Flexible Content
.layout {
    display: grid;

    grid-template-columns: 240px 1fr;
}
Two Sidebars and Main Content
.layout {
    display: grid;

    grid-template-columns: 220px 1fr 300px;
}
Mixed Track Layout
       220px             Flexible              300px

┌───────────────┬────────────────────────────┬──────────────────┐
│               │                            │                  │
│   Sidebar     │        Main Content        │  Right Sidebar   │
│               │                            │                  │
└───────────────┴────────────────────────────┴──────────────────┘

grid-template-rows

The grid-template-rows property defines the number and size of rows in the explicit grid.

Three Rows
.container {
    display: grid;

    grid-template-rows: 100px 200px 100px;
}
Flexible Rows
.container {
    display: grid;

    height: 600px;

    grid-template-rows: 100px 1fr 80px;
}
Page Rows
┌──────────────────────────────────────┐
│             Header 100px             │
├──────────────────────────────────────┤
│                                      │
│                                      │
│          Main Content 1fr            │
│                                      │
│                                      │
├──────────────────────────────────────┤
│             Footer 80px              │
└──────────────────────────────────────┘

Example 3: Rows & Columns

HTML
<div class="gallery">
    <div>1</div>
    <div>2</div>
    <div>3</div>
    <div>4</div>
</div>
CSS
.gallery {
    display: grid;

    grid-template-columns: 1fr 1fr;
    grid-template-rows: 120px 200px;

    gap: 12px;
}

.gallery div {
    display: grid;

    place-items: center;

    background: #6c5ce7;
    color: white;

    border-radius: 10px;
}

repeat() Function

The repeat() function avoids repeating the same track size multiple times.

Without repeat()
.container {
    grid-template-columns:
        1fr 1fr 1fr 1fr;
}
With repeat()
.container {
    grid-template-columns:
        repeat(4, 1fr);
}
Repeated Pattern
.container {
    grid-template-columns:
        repeat(3, 100px 1fr);
}
repeat() Improves Readability

Use repeat() when the same column or row pattern appears several times.

Example 4: Repeated Columns

HTML
<div class="stats">
    <div>120 Users</div>
    <div>45 Courses</div>
    <div>98% Success</div>
    <div>24 Projects</div>
</div>
CSS
.stats {
    display: grid;

    grid-template-columns: repeat(4, 1fr);

    gap: 16px;
}

Grid Gap

The gap property creates spacing between grid rows and columns.

Equal Gap
.container {
    display: grid;

    gap: 20px;
}
Separate Row and Column Gaps
.container {
    row-gap: 20px;
    column-gap: 30px;
}
Two-Value Gap
.container {
    gap: 20px 30px;
}

In the two-value syntax, the first value controls row spacing and the second value controls column spacing.

Example 5: Card Gap

HTML
<div class="cards">
    <div class="card">HTML</div>
    <div class="card">CSS</div>
    <div class="card">JavaScript</div>
    <div class="card">React</div>
</div>
CSS
.cards {
    display: grid;

    grid-template-columns: repeat(2, 1fr);

    gap: 24px;
}

.card {
    padding: 30px;

    background: #6c5ce7;
    color: white;

    border-radius: 12px;
}

Explicit & Implicit Grid

The explicit grid contains rows and columns that you define directly using grid-template-columns and grid-template-rows.

The implicit grid contains additional tracks automatically created by the browser when grid items do not fit inside the explicitly defined grid.

Explicit Grid

  • Defined by the developer.
  • Uses grid-template-columns.
  • Uses grid-template-rows.
  • Track sizes are intentionally specified.

Implicit Grid

  • Created automatically.
  • Appears when more tracks are needed.
  • Can use grid-auto-rows.
  • Can use grid-auto-columns.

grid-auto-rows

The grid-auto-rows property controls the size of automatically created implicit rows.

Automatic Row Size
.container {
    display: grid;

    grid-template-columns: repeat(3, 1fr);

    grid-auto-rows: 150px;
}

Every automatically created row will use a height of 150px.

grid-auto-columns

The grid-auto-columns property controls the size of automatically created implicit columns.

Automatic Column Size
.container {
    display: grid;

    grid-auto-flow: column;

    grid-auto-columns: 200px;
}

grid-auto-flow

The grid-auto-flow property controls how automatically placed grid items flow into the grid.

ValueBehavior
rowItems fill rows first
columnItems fill columns first
denseAttempts to fill earlier empty spaces
row denseRow flow with dense packing
column denseColumn flow with dense packing
Column Flow
.container {
    display: grid;

    grid-auto-flow: column;
}
Use dense Carefully

Dense packing can visually move later items into earlier gaps. This may create a visual order different from the document order.

Grid Item Placement

Grid items can be placed precisely by referencing numbered grid lines.

Column Line Numbers
Line 1       Line 2       Line 3       Line 4
  │             │             │             │
  ▼             ▼             ▼             ▼

  ┌─────────────┬─────────────┬─────────────┐
  │  Column 1   │  Column 2   │  Column 3   │
  └─────────────┴─────────────┴─────────────┘

A three-column grid has four vertical grid lines.

grid-column-start & End

Column Placement
.item {
    grid-column-start: 1;
    grid-column-end: 3;
}

The item begins at column line 1 and ends at column line 3, so it occupies two column tracks.

Column Span
Line 1       Line 2       Line 3       Line 4
  │             │             │             │
  ▼             ▼             ▼             ▼

  ┌───────────────────────────┬─────────────┐
  │                           │             │
  │       Grid Item           │ Empty Cell  │
  │                           │             │
  └───────────────────────────┴─────────────┘

  Start: 1                  End: 3

grid-column Shorthand

Longhand
.item {
    grid-column-start: 1;
    grid-column-end: 3;
}
Shorthand
.item {
    grid-column: 1 / 3;
}
Full Width
.item {
    grid-column: 1 / -1;
}
Use -1 for the Final Grid Line

grid-column: 1 / -1 is a common pattern for making an item span from the first explicit grid line to the last.

Example 6: Column Spanning

HTML
<div class="grid">
    <div class="featured">Featured Course</div>
    <div>HTML</div>
    <div>CSS</div>
    <div>JavaScript</div>
</div>
CSS
.grid {
    display: grid;

    grid-template-columns: repeat(3, 1fr);

    gap: 12px;
}

.featured {
    grid-column: 1 / -1;
}

grid-row-start & End

Row Placement
.item {
    grid-row-start: 1;
    grid-row-end: 3;
}

The item begins at row line 1 and ends at row line 3, occupying two row tracks.

grid-row Shorthand

Longhand
.item {
    grid-row-start: 1;
    grid-row-end: 3;
}
Shorthand
.item {
    grid-row: 1 / 3;
}

Example 7: Row Spanning

HTML
<div class="layout">
    <aside>Sidebar</aside>
    <header>Header</header>
    <main>Main Content</main>
</div>
CSS
.layout {
    display: grid;

    grid-template-columns: 220px 1fr;
    grid-template-rows: 100px 300px;

    gap: 12px;
}

aside {
    grid-row: 1 / 3;
}

The span Keyword

The span keyword tells a grid item how many tracks it should occupy.

Span Two Columns
.item {
    grid-column: span 2;
}
Span Three Rows
.item {
    grid-row: span 3;
}

Line-Based Placement

  • grid-column: 1 / 3
  • Uses exact line numbers.
  • Controls start and end.
  • Useful for precise layouts.

Span-Based Placement

  • grid-column: span 2
  • Uses number of tracks.
  • Works from current placement.
  • Useful for flexible card layouts.

Example 8: Dashboard Cards

HTML
<div class="dashboard">
    <div class="card large">Analytics</div>
    <div class="card">Users</div>
    <div class="card">Sales</div>
    <div class="card tall">Activity</div>
    <div class="card">Reports</div>
</div>
CSS
.dashboard {
    display: grid;

    grid-template-columns: repeat(3, 1fr);
    grid-auto-rows: 140px;

    gap: 16px;
}

.large {
    grid-column: span 2;
}

.tall {
    grid-row: span 2;
}

grid-area Shorthand

The grid-area property can define row start, column start, row end, and column end in one declaration.

grid-area Syntax
.item {
    grid-area:
        row-start /
        column-start /
        row-end /
        column-end;
}
Example
.item {
    grid-area: 1 / 1 / 3 / 4;
}

This item starts at row line 1 and column line 1, then ends at row line 3 and column line 4.

Named Grid Areas

Instead of relying only on line numbers, grid items can be assigned meaningful area names.

Naming Items
.header {
    grid-area: header;
}

.sidebar {
    grid-area: sidebar;
}

.main {
    grid-area: main;
}

.footer {
    grid-area: footer;
}

grid-template-areas

The grid-template-areas property creates a visual map of the layout using named grid areas.

Named Layout
.layout {
    display: grid;

    grid-template-columns: 220px 1fr;

    grid-template-areas:
        "header  header"
        "sidebar main"
        "footer  footer";
}
Area Map
┌──────────────────────────────────────┐
│               header                 │
├──────────────┬───────────────────────┤
│              │                       │
│   sidebar    │         main          │
│              │                       │
├──────────────┴───────────────────────┤
│               footer                 │
└──────────────────────────────────────┘
Area Names Must Form Rectangles

Each named grid area must form a rectangular region. You cannot create an L-shaped named area.

Example 9: Page Layout

HTML
<div class="page">
    <header>Header</header>
    <aside>Sidebar</aside>
    <main>Main Content</main>
    <footer>Footer</footer>
</div>
CSS
.page {
    display: grid;

    grid-template-columns: 220px 1fr;
    grid-template-rows: 90px 350px 70px;

    grid-template-areas:
        "header  header"
        "sidebar main"
        "footer  footer";

    gap: 12px;
}

header {
    grid-area: header;
}

aside {
    grid-area: sidebar;
}

main {
    grid-area: main;
}

footer {
    grid-area: footer;
}

Empty Grid Cells

A period can represent an intentionally empty cell inside grid-template-areas.

Empty Cell
.layout {
    grid-template-areas:
        "header header"
        "sidebar main"
        ". footer";
}

The period means that no named area occupies that grid cell.

Grid Alignment

CSS Grid provides properties for aligning items inside grid cells and for aligning the entire grid inside its container.

PropertyPurpose
justify-itemsAligns items horizontally inside cells
align-itemsAligns items vertically inside cells
place-itemsShorthand for align-items and justify-items
justify-contentAligns the entire grid horizontally
align-contentAligns the entire grid vertically
place-contentShorthand for align-content and justify-content
justify-selfAligns one item horizontally
align-selfAligns one item vertically

justify-items

The justify-items property aligns grid items along the inline axis inside their grid cells.

Horizontal Item Alignment
.container {
    display: grid;

    justify-items: center;
}
ValueBehavior
stretchItems stretch to fill available inline space
startItems align at the inline start
endItems align at the inline end
centerItems are centered horizontally

align-items

The align-items property aligns grid items along the block axis inside their grid cells.

Vertical Item Alignment
.container {
    display: grid;

    align-items: center;
}

place-items

The place-items property is a shorthand for align-items and justify-items.

Center Both Directions
.container {
    display: grid;

    place-items: center;
}
Two Values
.container {
    place-items: start center;
}

The first value controls align-items and the second controls justify-items.

Example 10: Centering Items

HTML
<div class="container">
    <div class="item">Centered</div>
</div>
CSS
.container {
    display: grid;

    place-items: center;

    height: 300px;

    background: #f5f6fa;
}

.item {
    padding: 30px;

    background: #6c5ce7;
    color: white;

    border-radius: 12px;
}

justify-content

The justify-content property aligns the entire grid horizontally when the grid is smaller than its container.

Center Entire Grid Horizontally
.container {
    display: grid;

    grid-template-columns:
        150px 150px 150px;

    justify-content: center;
}

align-content

The align-content property aligns the entire grid vertically when the grid is smaller than its container.

Center Entire Grid Vertically
.container {
    display: grid;

    height: 500px;

    grid-template-rows:
        100px 100px;

    align-content: center;
}

place-content

The place-content property is a shorthand for align-content and justify-content.

Center Entire Grid
.container {
    display: grid;

    place-content: center;
}
Items vs Content

Properties ending in -items align grid items inside their cells. Properties ending in -content align the entire grid inside the container.

justify-self & align-self

Individual grid items can override the container alignment using justify-self and align-self.

Individual Item Alignment
.special {
    justify-self: end;
    align-self: center;
}
PropertyPurpose
justify-selfAligns one item horizontally inside its cell
align-selfAligns one item vertically inside its cell

Example 11: Individual Alignment

HTML
<div class="grid">
    <div>1</div>
    <div class="special">2</div>
    <div>3</div>
</div>
CSS
.grid {
    display: grid;

    grid-template-columns: repeat(3, 1fr);

    height: 220px;

    gap: 12px;
}

.special {
    justify-self: center;
    align-self: end;
}

minmax() Function

The minmax() function defines a minimum and maximum size for a grid track.

Flexible Track
.container {
    grid-template-columns:
        minmax(200px, 1fr);
}

The track should not become smaller than 200px, but it can grow to use available space.

Three Flexible Columns
.container {
    grid-template-columns:
        repeat(3, minmax(150px, 1fr));
}
minmax() Is Essential for Responsive Grids

Combining minmax() with auto-fit or auto-fill creates powerful responsive layouts with very little CSS.

Example 12: Flexible Tracks

HTML
<div class="products">
    <div>Product 1</div>
    <div>Product 2</div>
    <div>Product 3</div>
</div>
CSS
.products {
    display: grid;

    grid-template-columns:
        repeat(3, minmax(150px, 1fr));

    gap: 20px;
}

auto-fit

The auto-fit keyword creates as many columns as can fit and collapses empty tracks so existing items can expand.

auto-fit Pattern
.container {
    display: grid;

    grid-template-columns:
        repeat(
            auto-fit,
            minmax(250px, 1fr)
        );
}
Measure Container Width
Check Minimum Track Width
Create Maximum Fitting Columns
Place Grid Items
Collapse Empty Tracks
Expand Existing Items

auto-fill

The auto-fill keyword creates as many columns as can fit and preserves empty tracks when there are fewer items than available columns.

auto-fill Pattern
.container {
    display: grid;

    grid-template-columns:
        repeat(
            auto-fill,
            minmax(250px, 1fr)
        );
}

auto-fit vs auto-fill

auto-fit

  • Creates fitting tracks.
  • Collapses empty tracks.
  • Existing items can expand.
  • Common for responsive cards.

auto-fill

  • Creates fitting tracks.
  • Keeps empty tracks.
  • Preserves the track structure.
  • Useful when empty slots matter.
Visual Difference
Container has room for 4 columns but only 2 items.


auto-fit

┌──────────────────────┬──────────────────────┐
│       Item 1         │        Item 2        │
└──────────────────────┴──────────────────────┘

Empty tracks collapse.


auto-fill

┌──────────┬──────────┬──────────┬──────────┐
│  Item 1  │  Item 2  │  Empty   │  Empty   │
└──────────┴──────────┴──────────┴──────────┘

Empty tracks remain.

Example 13: Responsive Grid

HTML
<div class="course-grid">
    <article class="course">
        <h3>HTML</h3>
        <p>Learn website structure.</p>
    </article>

    <article class="course">
        <h3>CSS</h3>
        <p>Learn website styling.</p>
    </article>

    <article class="course">
        <h3>JavaScript</h3>
        <p>Learn website interactivity.</p>
    </article>

    <article class="course">
        <h3>React</h3>
        <p>Build modern interfaces.</p>
    </article>
</div>
CSS
.course-grid {
    display: grid;

    grid-template-columns:
        repeat(
            auto-fit,
            minmax(220px, 1fr)
        );

    gap: 20px;
}

.course {
    padding: 24px;

    background: white;

    border: 1px solid #dfe6e9;

    border-radius: 14px;
}

Nested Grid

A grid item can also become a grid container for its own direct children.

Nested Grid Structure
<div class="page">
    <aside>Sidebar</aside>

    <main class="content">
        <div class="card">Card 1</div>
        <div class="card">Card 2</div>
        <div class="card">Card 3</div>
    </main>
</div>
Nested Grid
.page {
    display: grid;

    grid-template-columns: 220px 1fr;
}

.content {
    display: grid;

    grid-template-columns:
        repeat(3, 1fr);

    gap: 20px;
}
Nested Grid Layout
Outer Grid

┌──────────────┬──────────────────────────────────────┐
│              │          Inner Grid                  │
│              ├───────────┬───────────┬──────────────┤
│   Sidebar    │  Card 1   │  Card 2   │   Card 3     │
│              │           │           │              │
└──────────────┴───────────┴───────────┴──────────────┘

Grid vs Flexbox

CSS Grid

  • Primarily two-dimensional.
  • Controls rows and columns together.
  • Layout-driven.
  • Excellent for page structure.
  • Supports precise placement and spanning.

Flexbox

  • Primarily one-dimensional.
  • Controls one main direction at a time.
  • Content-driven.
  • Excellent for component alignment.
  • Ideal for navbars and item groups.
Layout NeedRecommended
Navigation barFlexbox
Page layoutGrid
ToolbarFlexbox
DashboardGrid
Card content alignmentFlexbox
Photo galleryGrid
Form action buttonsFlexbox
Complex rows and columnsGrid
Grid and Flexbox Work Together

A common approach is to use Grid for the main page structure and Flexbox for alignment inside individual components.

Complete Grid Example

The following example combines named grid areas, flexible tracks, responsive cards, spanning, gaps, nested layouts, and alignment in a practical dashboard.

HTML
<div class="dashboard">
    <header class="topbar">
        <div>
            <h2>Learning Dashboard</h2>
            <p>Welcome back</p>
        </div>

        <button>Profile</button>
    </header>

    <aside class="sidebar">
        <div class="brand">
            PrograMinds
        </div>

        <nav>
            <a href="#">Dashboard</a>
            <a href="#">Courses</a>
            <a href="#">Progress</a>
            <a href="#">Certificates</a>
        </nav>
    </aside>

    <main class="main">
        <section class="stats">
            <article class="stat">
                <span>Courses</span>
                <strong>12</strong>
            </article>

            <article class="stat">
                <span>Completed</span>
                <strong>8</strong>
            </article>

            <article class="stat">
                <span>Hours</span>
                <strong>96</strong>
            </article>
        </section>

        <section class="content-grid">
            <article class="progress-card">
                <h3>Course Progress</h3>

                <div class="progress-item">
                    <span>HTML</span>
                    <strong>100%</strong>
                </div>

                <div class="progress-item">
                    <span>CSS</span>
                    <strong>76%</strong>
                </div>

                <div class="progress-item">
                    <span>JavaScript</span>
                    <strong>45%</strong>
                </div>
            </article>

            <article class="activity-card">
                <h3>Recent Activity</h3>

                <p>Completed CSS Flexbox</p>
                <p>Started CSS Grid</p>
                <p>Earned HTML Certificate</p>
            </article>

            <article class="featured-card">
                <h3>Continue Learning</h3>

                <p>
                    CSS Complete Course
                </p>

                <button>
                    Continue Course
                </button>
            </article>
        </section>
    </main>

    <footer class="footer">
        © PrograMinds
    </footer>
</div>
CSS
.dashboard {
    display: grid;

    grid-template-columns: 230px 1fr;

    grid-template-rows:
        auto 1fr auto;

    grid-template-areas:
        "sidebar topbar"
        "sidebar main"
        "sidebar footer";

    min-height: 700px;

    background: #f5f6fa;

    border-radius: 18px;

    overflow: hidden;
}

.topbar {
    grid-area: topbar;

    display: flex;

    align-items: center;

    padding: 24px 30px;

    background: white;
}

.topbar button {
    margin-left: auto;
}

.sidebar {
    grid-area: sidebar;

    padding: 24px;

    background: #2d3436;
}

.brand {
    margin-bottom: 30px;

    color: white;

    font-size: 1.3rem;
    font-weight: bold;
}

.sidebar nav {
    display: grid;

    gap: 10px;
}

.sidebar a {
    padding: 12px;

    color: #dfe6e9;

    text-decoration: none;

    border-radius: 8px;
}

.main {
    grid-area: main;

    min-width: 0;

    padding: 30px;
}

.stats {
    display: grid;

    grid-template-columns:
        repeat(
            auto-fit,
            minmax(160px, 1fr)
        );

    gap: 20px;

    margin-bottom: 20px;
}

.stat {
    display: grid;

    gap: 10px;

    padding: 24px;

    background: white;

    border-radius: 14px;
}

.stat strong {
    font-size: 2rem;

    color: #6c5ce7;
}

.content-grid {
    display: grid;

    grid-template-columns:
        repeat(2, minmax(0, 1fr));

    grid-auto-rows: minmax(180px, auto);

    gap: 20px;
}

.progress-card {
    grid-row: span 2;
}

.progress-card,
.activity-card,
.featured-card {
    padding: 24px;

    background: white;

    border-radius: 14px;
}

.progress-item {
    display: flex;

    justify-content: space-between;

    padding: 16px 0;

    border-bottom: 1px solid #dfe6e9;
}

.featured-card {
    display: grid;

    align-content: center;

    background: #6c5ce7;

    color: white;
}

.footer {
    grid-area: footer;

    padding: 20px 30px;

    background: white;

    color: #636e72;
}

Browser Grid Flow

The browser calculates a Grid layout by identifying the grid container, creating explicit tracks, generating implicit tracks when necessary, placing items, calculating track sizes, and applying alignment.

Read HTML
Build Document Structure
Read CSS
Detect display: grid
Identify Direct Grid Items
Create Explicit Columns
Create Explicit Rows
Auto-Place Items
Create Implicit Tracks If Needed
Calculate Track Sizes
Apply Item Spanning
Apply Item Alignment
Apply Grid Alignment
Paint Final Layout
Grid Processing
Grid Container
      │
      ▼
Read Template Columns & Rows
      │
      ▼
Create Explicit Grid
      │
      ▼
Place Positioned Items
      │
      ▼
Auto-Place Remaining Items
      │
      ▼
Need More Tracks?
      │
   ┌──┴──┐
   │     │
  Yes    No
   │     │
Create   Continue
Implicit
Tracks
   │
   └──┬──┘
      │
      ▼
Calculate Track Sizes
      │
      ▼
Apply Alignment
      │
      ▼
Final Grid Layout

Real-World Applications

Dashboards

Arrange statistics, charts, tables, and activity panels.

Magazine Layouts

Create complex article and content arrangements.

Image Galleries

Build responsive galleries with different item sizes.

Product Grids

Display responsive product cards.

Page Layouts

Arrange headers, sidebars, main content, and footers.

Course Catalogs

Create flexible grids of learning content.

Application Interfaces

Build structured admin and productivity interfaces.

Responsive Components

Automatically adapt column counts to available space.

Advantages

Two-Dimensional Layout

Control rows and columns together.

Precise Placement

Place items using lines, spans, or named areas.

Responsive Design

Create adaptive layouts with auto-fit and minmax().

Flexible Spanning

Allow items to occupy multiple tracks.

Visual Layout Maps

Use grid-template-areas for readable page structures.

Flexible Sizing

Use fr, minmax(), auto, and mixed track sizes.

Built-In Alignment

Align individual items or the entire grid.

Cleaner Layout Code

Reduce the need for floats and positioning hacks.

Common Beginner Mistakes

Forgetting display: grid

Grid properties do not work until the parent becomes a grid container.

Applying Container Properties to Items

Properties such as grid-template-columns belong on the grid container.

Applying Item Properties to the Container

Properties such as grid-column and grid-row belong on grid items.

Expecting Nested Descendants to Become Grid Items

Only direct children participate in the parent grid.

Confusing Grid Lines and Columns

Three columns create four vertical grid lines.

Using the Wrong End Line

grid-column: 1 / 3 spans two columns, not three.

Forgetting the -1 Grid Line

Use 1 / -1 when an item should span the entire explicit grid width.

Using Too Many Fixed Pixel Columns

Fixed tracks can cause horizontal overflow on smaller screens.

Using Percentages with Large Gaps

Percentage tracks plus gaps can exceed the container width.

Treating fr as a Percentage

The fr unit distributes available space after other sizing requirements are considered.

Ignoring Implicit Tracks

Extra items can create rows or columns that were not explicitly defined.

Forgetting grid-auto-rows

Implicit rows may have unexpected sizes without an intentional auto-row rule.

Using dense Without Considering Order

Dense packing may create a visual order different from document order.

Creating Invalid Named Areas

Named grid areas must form rectangular shapes.

Using Different Area Names in Each Row

Each area name must match the grid-area assigned to the corresponding item.

Confusing justify-items and justify-content

justify-items aligns items inside cells, while justify-content aligns the entire grid.

Confusing align-items and align-content

align-items aligns items inside cells, while align-content aligns the entire grid.

Expecting content Alignment Without Extra Space

justify-content and align-content require unused space around the grid.

Using auto-fit and auto-fill Without minmax()

These keywords are commonly most useful when combined with a flexible minimum and maximum track size.

Using Grid for Every Small Alignment Task

Simple one-dimensional component alignment may be easier with Flexbox.

Best Practices

  • Apply display: grid to the parent container.
  • Remember that only direct children become grid items.
  • Use grid-template-columns to define explicit columns.
  • Use grid-template-rows to define explicit rows.
  • Use fr units for flexible track sizing.
  • Use repeat() to avoid repeating identical track definitions.
  • Use gap for spacing between rows and columns.
  • Prefer gap over margins for regular grid spacing.
  • Understand that grid lines define item placement.
  • Remember that three columns create four vertical grid lines.
  • Use grid-column for horizontal spanning.
  • Use grid-row for vertical spanning.
  • Use span when the number of occupied tracks matters more than exact line numbers.
  • Use 1 / -1 for full-width items across the explicit grid.
  • Use grid-template-areas for readable page layouts.
  • Give named areas meaningful names.
  • Keep named grid areas rectangular.
  • Use a period for intentionally empty cells in template areas.
  • Use grid-auto-rows to control implicit row sizes.
  • Use grid-auto-columns to control implicit column sizes.
  • Understand the difference between explicit and implicit grids.
  • Use grid-auto-flow intentionally.
  • Use dense packing carefully.
  • Keep document order logical even when visual placement changes.
  • Use justify-items for horizontal item alignment inside cells.
  • Use align-items for vertical item alignment inside cells.
  • Use place-items for concise two-axis item alignment.
  • Use justify-content to align the entire grid horizontally.
  • Use align-content to align the entire grid vertically.
  • Use place-content for concise whole-grid alignment.
  • Use justify-self for one item horizontal alignment.
  • Use align-self for one item vertical alignment.
  • Understand the difference between item alignment and content alignment.
  • Use minmax() for flexible minimum and maximum track sizes.
  • Use auto-fit with minmax() for common responsive card grids.
  • Use auto-fill when preserving empty tracks is intentional.
  • Understand the difference between auto-fit and auto-fill.
  • Use minmax(0, 1fr) when flexible tracks must be allowed to shrink fully.
  • Avoid unnecessary fixed pixel columns.
  • Use flexible tracks for responsive layouts.
  • Combine fixed sidebars with flexible main content when appropriate.
  • Test layouts with long content.
  • Test layouts with short content.
  • Test layouts with missing content.
  • Test layouts with dynamically added items.
  • Test layouts with one item.
  • Test layouts with many items.
  • Test narrow viewport widths.
  • Test wide viewport widths.
  • Test translated text.
  • Test large text settings.
  • Use Grid for two-dimensional structure.
  • Use Flexbox for one-dimensional component alignment.
  • Combine Grid and Flexbox when appropriate.
  • Use Grid for page-level layout.
  • Use Flexbox inside grid items when internal content needs simple alignment.
  • Avoid deeply nested grids without a clear reason.
  • Use semantic HTML with Grid.
  • Do not use Grid to replace meaningful document structure.
  • Keep source order accessible and logical.
  • Avoid using placement rules to create confusing reading order.
  • Use browser developer tools to inspect grid lines.
  • Use the Grid inspector when available.
  • Check explicit and implicit tracks during debugging.
  • Inspect line numbers before changing placement values.
  • Inspect available space when content alignment appears ineffective.
  • Inspect minimum content sizes when tracks refuse to shrink.
  • Use min-width: 0 on grid items when necessary.
  • Use overflow carefully inside grid areas.
  • Use auto rows for dynamically generated content.
  • Use meaningful class names for major grid areas.
  • Keep track definitions readable.
  • Break long grid-template declarations across multiple lines.
  • Document unusual spanning rules.
  • Avoid unexplained magic numbers.
  • Use repeat() for repeated patterns.
  • Use named areas for layouts that benefit from visual mapping.
  • Use line placement for precise component-level control.
  • Use span for flexible dashboard and gallery cards.
  • Use responsive grids instead of manually creating many breakpoint column counts when possible.
  • Add media queries when the overall page structure genuinely needs to change.
  • Do not depend on auto-fit for every responsive layout problem.
  • Use media queries to change named area layouts when necessary.
  • Ensure important content remains visible at small widths.
  • Prevent horizontal overflow caused by fixed tracks.
  • Account for gaps when using percentage tracks.
  • Prefer fr units when sharing available space.
  • Remember that fr units work with available space.
  • Use auto for content-sized tracks.
  • Use fixed values only when the design requires fixed tracks.
  • Use min-content and max-content only after understanding content-based sizing.
  • Start with a simple grid.
  • Add spanning only when necessary.
  • Add named areas only when they improve readability.
  • Add auto-placement controls only when default placement is insufficient.
  • Use the simplest Grid solution that clearly expresses the layout.
Remember the Core Grid Formula

Container: columns, rows, gaps, auto-placement, and alignment. Items: column placement, row placement, spanning, named areas, and individual alignment.

Frequently Asked Questions

What is CSS Grid?

CSS Grid is a two-dimensional layout system used to control rows and columns together.

How do I create a grid container?

Apply display: grid or display: inline-grid to a parent element.

What becomes a grid item?

Each direct child of a grid container becomes a grid item.

Do nested descendants automatically become grid items?

No. Only direct children participate in the parent grid.

What does grid-template-columns do?

It defines the number and size of columns in the explicit grid.

What does grid-template-rows do?

It defines the number and size of rows in the explicit grid.

What is the fr unit?

The fr unit represents a fraction of available space in a grid container.

Is 1fr the same as 50%?

No. fr units distribute available space and are not direct percentages.

What does repeat() do?

It repeats a track definition and makes grid templates shorter and easier to read.

What does gap do?

It creates spacing between grid rows and columns.

What is a grid line?

A grid line is a horizontal or vertical boundary between grid tracks.

What is a grid track?

A grid track is the space between two adjacent grid lines.

What is a grid cell?

A grid cell is the smallest area formed by one row and one column.

What is a grid area?

A grid area is a rectangular region containing one or more grid cells.

How many vertical lines does a three-column grid have?

A three-column grid has four vertical grid lines.

What does grid-column do?

It controls the column start and end positions of a grid item.

What does grid-row do?

It controls the row start and end positions of a grid item.

What does grid-column: 1 / -1 mean?

It makes an item span from the first explicit column line to the final explicit column line.

What does span mean?

The span keyword defines how many grid tracks an item should occupy.

What is the explicit grid?

The explicit grid contains tracks directly defined using grid-template-columns and grid-template-rows.

What is the implicit grid?

The implicit grid contains additional tracks automatically created when more rows or columns are needed.

What does grid-auto-rows do?

It defines the size of automatically created implicit rows.

What does grid-auto-columns do?

It defines the size of automatically created implicit columns.

What does grid-auto-flow do?

It controls how automatically placed grid items flow into the grid.

What does dense do?

Dense packing attempts to fill earlier empty spaces with later items.

What are named grid areas?

They are meaningful names assigned to grid items and arranged using grid-template-areas.

Can named grid areas be L-shaped?

No. Each named grid area must form a rectangle.

How do I create an empty cell in grid-template-areas?

Use a period to represent an intentionally empty grid cell.

What does justify-items do?

It aligns grid items horizontally inside their cells.

What does align-items do in Grid?

It aligns grid items vertically inside their cells.

What does place-items do?

It is a shorthand for align-items and justify-items.

What does justify-content do in Grid?

It aligns the entire grid horizontally when extra space exists.

What does align-content do in Grid?

It aligns the entire grid vertically when extra space exists.

What does place-content do?

It is a shorthand for align-content and justify-content.

What does justify-self do?

It horizontally aligns one grid item inside its cell.

What does align-self do?

It vertically aligns one grid item inside its cell.

What does minmax() do?

It defines a minimum and maximum size for a grid track.

What does auto-fit do?

It creates as many tracks as can fit and collapses empty tracks so existing items can expand.

What does auto-fill do?

It creates as many tracks as can fit while preserving empty tracks.

What is the difference between auto-fit and auto-fill?

auto-fit collapses empty tracks, while auto-fill preserves them.

How do I create a responsive grid without many media queries?

A common pattern is repeat(auto-fit, minmax(250px, 1fr)).

What is the difference between Grid and Flexbox?

Grid is primarily two-dimensional, while Flexbox is primarily one-dimensional.

Can Grid and Flexbox be used together?

Yes. Grid is often used for major structure while Flexbox handles alignment inside components.

When should I use CSS Grid?

Use Grid when rows and columns need to be controlled together, especially for page layouts, dashboards, galleries, and card systems.

What comes after CSS Grid?

The next lesson covers CSS Transform, including translate, rotate, scale, skew, transform-origin, multiple transforms, 2D and 3D transforms, perspective, and practical visual effects.

Key Takeaways

  • CSS Grid is a two-dimensional layout system.
  • display: grid creates a block-level grid container.
  • display: inline-grid creates an inline-level grid container.
  • Only direct children become grid items.
  • Grid layouts contain rows and columns.
  • Grid lines form the boundaries of grid tracks.
  • A grid cell is formed by one row and one column.
  • A grid area contains one or more rectangular cells.
  • grid-template-columns defines explicit columns.
  • grid-template-rows defines explicit rows.
  • The fr unit distributes available space.
  • repeat() simplifies repeated track definitions.
  • gap creates spacing between rows and columns.
  • Implicit tracks are created automatically when needed.
  • grid-auto-rows controls implicit row sizes.
  • grid-auto-columns controls implicit column sizes.
  • grid-auto-flow controls automatic item placement.
  • grid-column controls horizontal placement and spanning.
  • grid-row controls vertical placement and spanning.
  • The span keyword defines how many tracks an item occupies.
  • grid-template-areas creates readable visual layout maps.
  • Named grid areas must form rectangles.
  • justify-items and align-items align items inside cells.
  • justify-content and align-content align the entire grid.
  • place-items and place-content provide useful shorthands.
  • minmax() creates flexible track limits.
  • auto-fit collapses empty tracks.
  • auto-fill preserves empty tracks.
  • repeat(auto-fit, minmax(...)) is a powerful responsive grid pattern.
  • Grid is ideal for two-dimensional layouts.
  • Grid and Flexbox work well together.

Summary

CSS Grid is a modern two-dimensional layout system used to control rows and columns together.

A Grid layout begins by applying display: grid or display: inline-grid to a parent element.

The direct children of the container become grid items.

Grid layouts are formed using grid lines, tracks, cells, and areas.

The grid-template-columns property defines explicit columns, while grid-template-rows defines explicit rows.

The fr unit distributes available space between flexible tracks.

The repeat() function makes repeated track definitions shorter and easier to read.

The gap property creates consistent spacing between rows and columns.

The browser can automatically create implicit rows and columns when additional tracks are required.

Grid items can be placed and stretched using grid-column, grid-row, line numbers, and the span keyword.

Named grid areas provide a readable way to create page-level layouts.

Grid provides separate properties for aligning items inside cells and aligning the entire grid inside its container.

The minmax() function defines flexible minimum and maximum track sizes.

The auto-fit and auto-fill keywords can automatically create responsive columns.

The pattern repeat(auto-fit, minmax(250px, 1fr)) is commonly used for responsive card grids.

CSS Grid is ideal for dashboards, galleries, page structures, product grids, course catalogs, and other layouts that require control over rows and columns together.

Grid and Flexbox are complementary tools: Grid is excellent for two-dimensional structure, while Flexbox is excellent for one-dimensional alignment.

In the next lesson, you will learn CSS Transform, including translate, rotate, scale, skew, transform-origin, multiple transforms, 2D and 3D transforms, perspective, and practical visual effects.