Overview

CSS Grid is the first layout system designed specifically for two-dimensional layouts. It lets you control rows and columns simultaneously, place items anywhere on the grid, and create responsive designs without media query gymnastics. This tutorial covers the fundamentals with practical examples.

Grid vs Flexbox

AspectGridFlexbox
DimensionsRows and columnsSingle axis
Item placementExplicit line-based positioningFlow along an axis
Best use casePage layouts, dashboards, image galleriesToolbars, rows of cards, centering

Defining a Grid

.container {
  display: grid;
  grid-template-columns: 200px 1fr 200px;
  grid-template-rows: auto 1fr auto;
  gap: 16px;
}

This creates a three-column layout with fixed sidebars and a flexible center column, plus a header, content area, and footer.

The fr Unit

fr represents a fraction of the available space. It is unique to Grid and replaces percentage-based math.

.container {
  display: grid;
  grid-template-columns: 1fr 2fr 1fr;
}

The middle column is twice as wide as the side columns.

repeat() and minmax()

/* Five equal columns */
grid-template-columns: repeat(5, 1fr);

/* Responsive columns that never shrink below 250px */
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));

The auto-fit and auto-fill keywords create as many columns as will fit in the container — the foundation of responsive card grids without media queries.

KeywordBehavior
auto-fitCollapses empty tracks so items stretch to fill the row
auto-fillKeeps empty tracks, so items keep their column width

Placing Items

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

.sidebar {
  grid-row: 2 / 4;
  grid-column: 1 / 2;
}

.content {
  grid-column: 2 / 4;
}

Lines are numbered starting at 1. Negative numbers count from the end, so -1 is the last line.

Named Lines and Areas

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

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

grid-template-areas produces the most readable layout code and is easy to reshape for responsive breakpoints.

Alignment

PropertyAxisCommon values
justify-itemsInline (columns)start, center, end, stretch
align-itemsBlock (rows)Same as above
justify-contentWhole grid inlinestart, center, space-between
align-contentWhole grid blockSame as above
place-itemsBoth axesShorthand for align-items + justify-items

Practical Example: Responsive Gallery

.gallery {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 1rem;
}

.gallery img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
}

.featured {
  grid-column: span 2;
  grid-row: span 2;
}

Common Mistakes

  • Applying grid properties to items instead of the container. grid-template-columns belongs on the grid parent.
  • Forgetting gap. Use gap instead of margins; it does not add outer spacing.
  • Over-nesting grids. A nested grid inherits nothing; define columns explicitly.
  • Using Grid for single-axis layouts. Flexbox is simpler for a row of buttons.