CSS Grid: The Complete Guide

CSS Grid is the most powerful layout system in CSS — it gives you control over rows and columns simultaneously. This guide covers everything from basic grids to named areas and responsive patterns. Want to build grids visually? Use the free CSS Grid generator →

How CSS Grid works

CSS Grid gives you control over rows and columns simultaneously. Unlike flexbox (which is one-dimensional), grid lets you place items in a two-dimensional layout with precise control over both axes.

.container {
  display: grid;
  grid-template-columns: 1fr 2fr 1fr;   /* 3 columns */
  grid-template-rows: auto 1fr auto;     /* 3 rows */
  gap: 16px;                             /* space between cells */
}

Defining the grid

grid-template-columns / grid-template-rows

/* Fixed widths */
grid-template-columns: 200px 300px 200px;

/* Fractional units (proportional) */
grid-template-columns: 1fr 2fr 1fr;     /* 25% / 50% / 25% */

/* Mixed */
grid-template-columns: 250px 1fr;       /* fixed sidebar + fluid main */

/* repeat() shorthand */
grid-template-columns: repeat(3, 1fr);  /* 3 equal columns */
grid-template-columns: repeat(4, 200px);

/* Auto-fill / auto-fit (responsive without media queries!) */
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));

/* Rows */
grid-template-rows: 60px 1fr 40px;      /* header, main, footer */
auto-fill vs auto-fit: auto-fill creates as many tracks as will fit, leaving empty tracks if there aren't enough items. auto-fit collapses empty tracks so items stretch to fill the space. For most card grids, auto-fit is what you want.

gap

gap: 16px;               /* same gap for rows and columns */
row-gap: 24px;           /* vertical gaps only */
column-gap: 12px;        /* horizontal gaps only */
gap: 24px 12px;          /* row-gap column-gap */

Placing items

/* By line numbers (1-indexed) */
.item {
  grid-column: 1 / 3;    /* spans from line 1 to line 3 (2 columns) */
  grid-row: 1 / 2;       /* first row */
}

/* Span shorthand */
.item {
  grid-column: span 2;   /* span 2 columns from wherever it lands */
  grid-row: span 3;      /* span 3 rows */
}

/* Named lines */
grid-template-columns: [sidebar-start] 250px [sidebar-end main-start] 1fr [main-end];
.sidebar { grid-column: sidebar-start / sidebar-end; }
.main    { grid-column: main-start / main-end; }

Named areas (the visual layout method)

.container {
  display: grid;
  grid-template-columns: 250px 1fr;
  grid-template-rows: 60px 1fr 40px;
  grid-template-areas:
    "header  header"
    "sidebar main"
    "footer  footer";
  gap: 16px;
}

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

This is the most readable way to define page layouts. The string grid literally maps to how the page looks.

Live demo

Header
Sidebar
Main

A classic page layout using grid-template-areas.

Copy-paste grid patterns

/* Responsive card grid (no media queries) */
.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 24px;
}

/* Holy grail layout */
.page {
  display: grid;
  grid-template-columns: 250px 1fr 200px;
  grid-template-rows: auto 1fr auto;
  grid-template-areas:
    "header header header"
    "nav    main   aside"
    "footer footer footer";
  min-height: 100vh;
}

/* Equal-height card row */
.equal-cards {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
  align-items: stretch;
}

/* Masonry-style (CSS only, experimental) */
.masonry {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: masonry;
  gap: 16px;
}

/* Centered single column (blog layout) */
.blog {
  display: grid;
  grid-template-columns: minmax(0, 720px);
  justify-content: center;
  padding: 0 24px;
}

Alignment

/* Align all items within their cells */
justify-items: start | end | center | stretch;  /* horizontal */
align-items: start | end | center | stretch;     /* vertical */
place-items: center;  /* shorthand: both axes */

/* Align the grid itself within the container */
justify-content: start | end | center | space-between | space-around;
align-content: start | end | center | space-between | space-around;

/* Align a single item */
.item {
  justify-self: center;
  align-self: end;
}

Grid in Tailwind CSS

<div class="grid grid-cols-3 gap-4">
  <div class="col-span-2">Wide</div>
  <div>Normal</div>
</div>

<!-- Responsive card grid -->
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6">
  <div>Card</div>
  <div>Card</div>
  <div>Card</div>
</div>

Key utilities: grid, grid-cols-*, grid-rows-*, col-span-*, row-span-*, gap-*, place-items-*, auto-cols-*, auto-rows-*.

Grid vs Flexbox

Common grid gotchas

Build grids visually

Set columns, rows, and gaps with sliders — see the grid update in real time and copy the CSS.

Open the Grid Generator →

FAQ

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

auto-fill creates as many tracks as will fit, leaving empty ones visible. auto-fit collapses empty tracks so items stretch to fill the space. For responsive card grids, auto-fit is usually what you want.

How do I make a responsive grid without media queries?

Use grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)). Items will automatically wrap to new rows when they can't fit at the minimum size.

What is the fr unit?

fr stands for "fraction of available space." 1fr 2fr 1fr creates three columns where the middle one is twice as wide as the others.

Should I use Grid or Flexbox?

Use Grid for two-dimensional layouts (page layouts, card grids). Use Flexbox for one-dimensional layouts (navbars, button groups). Combine them: Grid for the outer layout, Flexbox for components inside each cell.

Related tools