CSS Grid

CSS Grid is a two-dimensional layout system. Use it when you need to control both rows and columns at the same time. Flexbox is better for one-dimensional layouts (a single row or column); Grid is better for two-dimensional page layouts and complex component structures.

display: grid

Setting display: grid on an element makes it a grid container. Its direct children become grid items.

.container {
  display: grid;
}

By itself this does nothing visible. You define the structure with grid-template-columns and grid-template-rows.

grid-template-columns

grid-template-columns defines how many columns the grid has and how wide each one is.

The fr unit distributes available space proportionally. 1fr 1fr 1fr creates three equal columns.

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

/* Shorthand with repeat() */
.container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
}

You can mix fixed and flexible widths:

.layout {
  display: grid;
  grid-template-columns: 260px 1fr; /* Fixed sidebar, flexible main area */
}

grid-template-rows

grid-template-rows defines row heights. You often do not need this because rows size to their content by default. It is useful when you want consistent row heights across a grid of cards.

.card-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 200px);
}

gap

gap adds space between rows and columns. A single value applies to both.

.container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 24px;
}

Use two values to set row and column gap separately:

.container {
  gap: 16px 32px; /* row-gap column-gap */
}

Spanning columns and rows

By default each grid item occupies one cell. Use grid-column and grid-row to make an item span multiple cells.

.header {
  grid-column: 1 / 3; /* From column line 1 to column line 3 (spans 2 columns) */
}

.sidebar {
  grid-row: 1 / 3; /* Spans 2 rows */
}

/* The span keyword is often easier to read */
.featured {
  grid-column: span 2;
}

Responsive grids with auto-fill

auto-fill combined with minmax() creates a grid that adds or removes columns automatically based on available space, with no media queries needed.

.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 16px;
}

minmax(200px, 1fr) means each column is at least 200px wide, but grows to fill space if there is room. As the viewport shrinks, columns drop to the next line automatically.

Use auto-fit instead of auto-fill if you want existing columns to stretch to fill the row when there are fewer items than would fill it.

grid-template-areas

grid-template-areas lets you name regions of the grid and assign elements to them by name. This makes the layout structure easy to read.

.page {
  display: grid;
  grid-template-columns: 200px 1fr;
  grid-template-rows: auto 1fr auto;
  grid-template-areas:
    "header  header"
    "sidebar main"
    "footer  footer";
  min-height: 100vh;
}

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

Aligning items

justify-items aligns items horizontally within their cells. align-items aligns them vertically. The shorthand place-items sets both at once.

.container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  place-items: center; /* Center horizontally and vertically in each cell */
}

Practical examples

Two-column layout with a sidebar

.layout {
  display: grid;
  grid-template-columns: 260px 1fr;
  gap: 32px;
  max-width: 1200px;
  margin: 0 auto;
}

Responsive product card grid

.products {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 20px;
}

Grid vs Flexbox

Use Grid whenUse Flexbox when
You need rows and columns at the same timeYou need a single row or a single column
Building a full page layoutAligning items inside a component
You want items to line up across rowsYou want items to wrap and size to content

Grid and Flexbox work well together. A page-level grid can contain flex containers inside each cell.

  • Flexbox : one-dimensional layout for rows and columns
  • Responsive Design : media queries and breakpoints to adapt Grid layouts to different screen sizes