CSS Grid

Advanced
Layout

Two-dimensional layout: you define rows and columns, and place items into them. It handles page structure and card grids that flexbox can only approximate.

Overview

Grid is the first CSS layout system designed for layout rather than adapted to it. You describe a structure of rows and columns on the container and place children into it, which means alignment is guaranteed in both directions rather than being an emergent property of content sizes. The pieces worth learning properly are the fr unit, repeat with auto-fit and minmax — which produces a responsive card grid with no media queries at all — and named template areas, which make a page layout readable at a glance.

Defining a Grid

Columns, rows, fr, and gap.

fr, repeat, minmax(0, 1fr), line placement
.grid {
  display: grid;
  grid-template-columns: 200px 1fr 200px;   /* three columns */
  grid-template-rows: auto 1fr auto;
  gap: 1rem;                                 /* row and column gap */
}

/* fr = a fraction of the FREE space, after fixed tracks and gaps.
   This is why 1fr behaves and 33.33% overflows once gap is added. */
grid-template-columns: 1fr 2fr;      /* one third, two thirds */
grid-template-columns: repeat(3, 1fr);
grid-template-columns: repeat(4, minmax(0, 1fr));   /* see below */

/* minmax(0, 1fr) instead of 1fr is the grid equivalent of the flex
   min-width: 0 fix — a track's default minimum is 'auto', so wide
   content stretches the column and breaks the layout. */

/* Placing items by line number (lines, not tracks — 4 lines for
   3 columns) */
.item { grid-column: 1 / 3 }        /* from line 1 to line 3 */
.item { grid-column: span 2 }       /* however many, span two */
.item { grid-column: 1 / -1 }       /* full width, whatever the count */
.item { grid-row: 2 / 4 }

/* Alignment works on both axes, with the same vocabulary */
place-items: center;                /* align-items + justify-items */
place-content: center;              /* the whole grid within the box */

Responsive Without Media Queries

The auto-fit pattern — one line that replaces four breakpoints.

auto-fit + minmax, and subgrid
.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(16rem, 100%), 1fr));
  gap: 1.5rem;
}

/* Read it as: fit as many columns as possible, each at least 16rem
   and at most an equal share. Four columns on a desktop, two on a
   tablet, one on a phone — with no media query.

   The min(16rem, 100%) guards a viewport narrower than 16rem, where
   a bare minmax(16rem, 1fr) would overflow. */

/* auto-fit vs auto-fill:
     auto-fit   collapses empty tracks, so three cards stretch to fill
     auto-fill  keeps empty tracks, so three cards stay card-sized  */

/* Implicit rows — items beyond your defined tracks still get placed */
grid-auto-rows: minmax(8rem, auto);
grid-auto-flow: dense;      /* backfill holes left by spanning items */

/* Subgrid — children align to the PARENT's tracks, which is how you
   make card titles and buttons line up across a row regardless of
   how long each card's text is */
.card { display: grid; grid-row: span 3; grid-template-rows: subgrid }

Template Areas

Named regions — the most readable way to express a page layout.

grid-template-areas, and DOM order matters
.layout {
  display: grid;
  grid-template-areas:
    "header header"
    "sidebar main"
    "footer footer";
  grid-template-columns: 250px 1fr;
  grid-template-rows: auto 1fr auto;
  min-height: 100dvh;
}
.layout > header  { grid-area: header }
.layout > .side   { grid-area: sidebar }
.layout > main    { grid-area: main }
.layout > footer  { grid-area: footer }

/* Rearranging for mobile is one redefinition */
@media (max-width: 768px) {
  .layout {
    grid-template-areas: "header" "main" "sidebar" "footer";
    grid-template-columns: 1fr;
  }
}
/* Note the sidebar moved BELOW main visually — but the DOM order is
   unchanged, so the tab order still goes main then sidebar. Visual
   reordering that contradicts DOM order confuses keyboard users;
   keep them aligned where you can. */

/* Choosing between grid and flexbox:
     grid    — page structure, card grids, anything two-dimensional,
               or where you want alignment across rows
     flexbox — one row or column, sizes driven by content            */

Key Points to Remember

  • 1fr distributes free space after fixed tracks and gaps, which is why it behaves where percentages overflow
  • 2minmax(0, 1fr) prevents wide content stretching a track, the grid equivalent of min-width: 0
  • 3repeat(auto-fit, minmax(min(16rem, 100%), 1fr)) gives a fully responsive card grid with no media queries
  • 4grid-template-areas expresses a page layout readably and can be redefined per breakpoint
  • 5Visual reordering does not change tab order — keep DOM order and visual order aligned for keyboard users

Interview Questions

Sign in to ask Aria
1

When would you use grid rather than flexbox?

Medium
2

Explain repeat(auto-fit, minmax(200px, 1fr)).

Hard
3

Why is minmax(0, 1fr) often needed instead of plain 1fr?

Hard

Ask Aria about CSS Grid

Your personal AI tutor — ask anything about this concept

Revision Status

Personal Notes

Sign in to save personal notes for this topic.

Discussion

Sign in to join the discussion.

Loading discussion…