Guides / CSS
grid_view

CSS Grid Layout: Complete Guide with Examples

CSS Grid is the most powerful layout system in CSS. Unlike Flexbox (one-dimensional), Grid handles rows and columns simultaneously — perfect for page layouts, card grids, and complex UI patterns.

April 2026 · 10 min read

Grid vs Flexbox: When to Use Each

Use CSS Grid when you need two-dimensional control (rows AND columns). Use Flexbox when you're laying out items in a single row or column. The two work best together: Grid for page-level layout, Flexbox for component-level layout.

Grid vs Flexbox at a Glance

FeatureCSS GridFlexbox
Dimensions2D (rows + columns)1D (row or column)
Content flowGrid defines structureContent defines structure
Best forPage layouts, galleriesNav bars, button groups
AlignmentBoth axes alwaysCross-axis only
Browser support97%+ globally99%+ globally

Grid Basics: Columns and Rows

/* Define a 3-column grid */
.container {
  display: grid;
  grid-template-columns: 200px 1fr 200px;
  grid-template-rows: auto 1fr auto;
  gap: 1rem;
}

/* fr unit = fraction of remaining space */
.container {
  grid-template-columns: 1fr 2fr 1fr; /* 25% 50% 25% */
}

/* repeat() shorthand */
.container {
  grid-template-columns: repeat(3, 1fr); /* 3 equal columns */
  grid-template-rows: repeat(2, minmax(100px, auto));
}

grid-template-areas: Named Layout

The most readable way to define a page layout. Name each area and assign elements to them.

.layout {
  display: grid;
  grid-template-columns: 240px 1fr;
  grid-template-rows: 60px 1fr 60px;
  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; }

/* Stack on mobile */
@media (max-width: 768px) {
  .layout {
    grid-template-columns: 1fr;
    grid-template-areas:
      "header"
      "main"
      "sidebar"
      "footer";
  }
}

auto-fill vs auto-fit: Responsive Grids Without Media Queries

auto-fill creates as many tracks as possible, even if empty. auto-fit collapses empty tracks and expands filled ones. For responsive card grids, auto-fit is almost always what you want.

/* auto-fit: items expand to fill the row */
.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 1.5rem;
}

/* auto-fill: keeps ghost columns */
.fixed-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 1.5rem;
}

/* Result: auto-fit with 1 card → card fills full width
   auto-fill with 1 card → card stays 280px min */

Placing Items: Lines and Spans

/* Place by line numbers (1-indexed) */
.hero {
  grid-column: 1 / 3;  /* span columns 1 and 2 */
  grid-row: 1 / 2;
}

/* span keyword */
.featured {
  grid-column: span 2;  /* span 2 columns from current position */
  grid-row: span 3;
}

/* Negative lines: count from end */
.full-width {
  grid-column: 1 / -1;  /* always full width regardless of column count */
}

Grid Alignment

/* Align ALL items in their cells */
.container {
  align-items: center;    /* vertical in cell */
  justify-items: start;   /* horizontal in cell */
  place-items: center;    /* shorthand for both */
}

/* Align the entire grid within the container */
.container {
  align-content: space-between;  /* vertical distribution */
  justify-content: center;        /* horizontal distribution */
}

/* Override per-item */
.item {
  align-self: end;
  justify-self: stretch;
}

Subgrid: Aligning Nested Grids

Subgrid (supported in all modern browsers since 2023) lets child grids inherit the parent's track sizing — essential for aligned card content.

/* Parent grid */
.card-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: auto;
  gap: 1rem;
}

/* Each card spans 3 rows and uses subgrid */
.card {
  display: grid;
  grid-row: span 3;
  grid-template-rows: subgrid; /* inherit parent row tracks */
}

/* Now all card headings, bodies, and footers align */
.card-heading { grid-row: 1; }
.card-body    { grid-row: 2; }
.card-footer  { grid-row: 3; }

Real-World: Magazine Layout

/* 12-column magazine grid */
.magazine {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  grid-auto-rows: minmax(60px, auto);
  gap: 1rem;
}

.hero-story    { grid-column: 1 / 9;  grid-row: 1 / 4; }
.side-story-1  { grid-column: 9 / 13; grid-row: 1 / 2; }
.side-story-2  { grid-column: 9 / 13; grid-row: 2 / 4; }
.story-strip   { grid-column: 1 / -1; grid-row: 4 / 5; }

Common CSS Grid Mistakes

  • Using fixed px columns for responsive layouts — use fr units and minmax() instead.
  • Over-specifying rowsgrid-auto-rows: minmax(100px, auto) handles dynamic content better than fixed heights.
  • Forgetting gap vs margingap applies between grid items, not on the outside edges. Use padding on the container for outer spacing.
  • Using floats inside a grid — floats have no effect inside grid containers. Use alignment properties.
  • Not using grid-column: 1 / -1 for full-width items — it works regardless of how many columns you have.

Frequently Asked Questions

Does CSS Grid replace Flexbox?
No — they complement each other. Grid is for 2D layout (page structure, card grids), Flexbox is for 1D layout (navigation rows, button groups). Most modern UIs use both.
What does fr mean in CSS Grid?
fr is a fractional unit. 1fr means 'one fraction of the available space'. repeat(3, 1fr) creates 3 equal-width columns that share the total space after fixed/auto columns are resolved.
How do I center a single item with Grid?
Set the container to display: grid; place-items: center; — this is the shortest, most reliable way to center anything in CSS.
Is CSS Grid supported in all browsers?
Yes — CSS Grid has 97%+ global support. Subgrid reached full support in late 2023 (all evergreen browsers). Safe to use without fallbacks for modern web projects.