Part 4: CSS Grid

Introduction

Flexbox handles one dimension at a time — a row or a column. CSS Grid handles two dimensions simultaneously — rows and columns together. For page-level layouts and anything that needs items aligned in both directions at once, Grid is the right tool.

I use Grid mainly for page structure (header, sidebar, main, footer arranged in a two-dimensional space) and for uniform card grids where items should align across both rows and columns. This part covers every Grid property I use and the patterns that come up most often.


The Grid Mental Model

Grid works on two elements: a grid container and its direct grid items.

<div class="grid">      <!-- grid container -->
  <div>Item 1</div>
  <div>Item 2</div>
  <div>Item 3</div>
  <div>Item 4</div>
</div>
.grid {
  display: grid;
}

The container defines the track structure (columns and rows). Items are placed into cells formed by the intersection of tracks.


Defining Columns and Rows

grid-template-columns

grid-template-rows

The fr Unit

fr stands for "fraction of available space". It distributes remaining space after fixed-size tracks are accounted for.


The repeat() Function

auto-fill vs auto-fit

Both fill the container with as many columns as will fit at the minimum size. The difference is visible when items do not fill the last row:

  • auto-fill — empty columns are created and take space

  • auto-fit — empty columns collapse to 0, items expand to fill

For card grids, auto-fit is usually what I want.


The minmax() Function

Defines a size range for a track: minmax(minimum, maximum).

This single line creates a fully responsive grid: many columns on wide screens, fewer on narrow, no media query needed.


gap


Named Template Areas

grid-template-areas allows placing items by name rather than by line numbers — ideal for page-level layouts because the layout is visible in the CSS itself.

Use . for empty cells:


Placing Items with Line Numbers

Grid lines are numbered starting from 1. Items can span across lines using grid-column and grid-row.


Implicit Grid

When items are placed outside the explicitly defined tracks, the browser creates implicit tracks automatically.

grid-auto-flow

Controls how auto-placed items fill the grid.

dense is useful for masonry-like layouts where items have varying row spans and you want to fill holes.


Alignment in Grid

Grid has full alignment control in both dimensions.

Container-level (aligns all items)

Distributing the grid tracks within the container

Item-level overrides


Naming Grid Lines

Grid lines can be named for more readable placement:


Common Grid Patterns

Responsive Card Grid (No Media Query)

Cards reflow automatically: 3 columns on wide screens, 2 on medium, 1 on mobile.

Holy Grail Layout

Mobile-first: single column. Wider screens: sidebar + content.

Dashboard Grid

Centring with Grid


Flexbox vs Grid — When to Use Each

I decide based on the layout direction:

Use case
Tool

Items in one row/column (nav bar, button group)

Flexbox

Content-first sizing (items define track sizes)

Flexbox

Two-dimensional alignment (rows and columns together)

Grid

Layout-first design (define tracks then fill them)

Grid

Responsive card grid without media queries

Grid

Page-level layout (header, sidebar, main, footer)

Grid

In practice, I often use both: Grid for the page structure and Flexbox inside components.


Summary

Property
Purpose

display: grid

Activates grid layout

grid-template-columns

Define column tracks

grid-template-rows

Define row tracks

fr unit

Fraction of available space

repeat(n, size)

Repeat track definitions

auto-fit / auto-fill

Create as many columns as fit

minmax(min, max)

Track size range

gap

Space between tracks

grid-template-areas

Name-based area placement

grid-column / grid-row

Place items on specific lines

grid-auto-rows

Implicit track sizing

grid-auto-flow: dense

Fill gaps with smaller items

place-items: center

Centre all items in both axes

place-self: center

Centre a single item

grid-column: 1 / -1

Span full width


Up Next

Part 5 covers CSS custom properties, responsive design with media queries, and modern CSS features.

Last updated