CSS Layout

CSS Grid

CSS Grid is a two-dimensional layout system that lets you arrange elements in rows and columns. Learn how it works, when to use it, and how to build modern layouts without hacks.

beginner14 min readUpdated Sep 15, 2026
grid.css
css
/* grid.css */
.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 1.5rem;
}
Introduced
CSS3, 2012
Dimension
Two-dimensional (rows and columns)
Specification
W3C CSS Grid Layout Module Level 1
Browser support
All modern browsers
Best for
Complex page layouts and component grids

Hands-on

Try CSS Grid live

Edit the CSS to change grid-template-columns and see how items reflow.

Try CSS Grid live

Edit the CSS to change grid-template-columns and see how items reflow.

Why it matters

Why CSS Grid matters

Two-dimensional layout

Grid handles rows and columns at the same time, so you can place items anywhere on a two-dimensional plane without floats or positioning hacks.

Template areas

Name regions of your layout and place items by name, making complex designs readable and easy to rearrange.

Responsive by default

Combine auto-fit, auto-fill and minmax to create responsive grids that adapt without media queries.

The big picture

The three ideas behind Grid

Tracks define the columns and rows, lines place items, and areas let you draw a layout with names.

Tracks

Define

grid-template-columns and grid-template-rows create the columns and rows, sized with fr, minmax and auto.

Lines

Place

Numbered lines place items explicitly with grid-column and grid-row.

Areas

Name

grid-template-areas draws a layout with names, and grid-area assigns items into them.

Grid at a glance

The core concepts

Two-dimensional

Controls both rows and columns in a single declaration.

Template areas

Name layout regions and place items by name.

Precise placement

Position items on specific grid lines or areas.

Flexible sizing

The fr unit distributes remaining space proportionally.

Repeat patterns

repeat(), auto-fill and auto-fit for consistent columns.

Responsive

Adaptive layouts without media queries using minmax().

A short history

The road to native grid

  1. 2011

    Early proposals

    CSS Grid concepts appear in early W3C drafts, building on IE's proprietary `-ms-grid`.

    11
  2. 2012

    Grid Level 1

    The first official CSS Grid Layout specification enters Candidate Recommendation.

    12
  3. 2017

    Browser support

    Chrome, Firefox, Safari and Edge ship unprefixed CSS Grid.

    17
  4. 2020

    Subgrid

    Subgrid support lands in Firefox, allowing nested grids to inherit parent tracks.

    20
  5. Today

    Grid Level 2

    Container queries and the :has() pseudo-class complement Grid for component-level layouts.

    Today

The complete guide

CSS Grid: Everything you need to know

What is CSS Grid?

CSS Grid is a two-dimensional layout system built into CSS. It lets you arrange elements in rows and columns simultaneously, giving you full control over how items are placed, sized and aligned on a page. Before Grid, developers relied on floats, tables or positioning hacks to create complex layouts. Grid replaced all of that with a single, powerful mechanism.

The key distinction is two dimensions. Flexbox arranges items in a single direction — a row or a column. Grid arranges items in both directions at once: you define columns and rows, and then place items into the resulting cells. That makes it the natural choice for page-level layouts, card grids, dashboards and any design where items need to sit in a structured, two-dimensional plane.

Grid container and grid items

To use Grid you set display: grid on a parent element. That parent becomes the grid container, and its direct children become grid items.

/* style.css */
.container {
  display: grid;
}

Once the container is a grid, you define how many columns and rows it has, how wide they are, and how items are placed inside them. Items that are not explicitly placed are automatically positioned by the grid algorithm, filling empty cells in order.

Grid template columns and rows

The most fundamental Grid properties are grid-template-columns and grid-template-rows. They define the tracks — the columns and rows — of your grid.

/* style.css */
.grid {
  display: grid;
  grid-template-columns: 200px 1fr 2fr;
  grid-template-rows: auto 1fr auto;
}
  • 200px 1fr 2fr creates three columns: a fixed 200-pixel column, then two flexible columns that split the remaining space in a 1-to-2 ratio.
  • auto 1fr auto creates three rows: the first and last shrink-wrap their content, while the middle row stretches to fill available height.

You can also use grid-template-columns shorthand to define everything in one place:

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

The fr unit

The fr unit stands for fraction of remaining space. It distributes available space proportionally among tracks after fixed sizes have been accounted for.

/* style.css */
.grid {
  grid-template-columns: 1fr 1fr 1fr; /* three equal columns */
}
/* style.css */
.grid {
  grid-template-columns: 200px 1fr 2fr; /* fixed + two flexible columns */
}

In the second example the first column takes 200 pixels, then the rest is split so the third column gets twice the space of the second. The fr unit is the most common way to size Grid tracks because it scales naturally with the container.

repeat(), auto-fill and auto-fit

Writing the same value multiple times is tedious. The repeat() function lets you repeat a track pattern:

/* style.css */
.grid {
  grid-template-columns: repeat(4, 1fr); /* four equal columns */
}

auto-fill and auto-fit go further. They repeat a track pattern as many times as it fits in the container:

/* style.css */
.grid {
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
}
  • auto-fill creates as many tracks as will fit, even if some remain empty.
  • auto-fit collapses empty tracks, stretching the remaining ones to fill the space.

In practice they behave identically when combined with minmax(), so the choice rarely matters.

minmax()

minmax() defines a track size range — a minimum and maximum:

minmax(200px, 1fr)

This means the track will be at least 200 pixels wide but can grow up to 1fr of the remaining space. Combined with auto-fill or auto-fit, minmax() is the engine behind responsive grids that adapt without media queries.

Grid gap

The gap property sets the spacing between grid items:

/* style.css */
.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.5rem;
}

You can set row and column gaps independently:

/* style.css */
.grid {
  row-gap: 1rem;
  column-gap: 2rem;
}

Gap only creates space between items, not around the edges of the container, which makes it cleaner than adding margins to grid items.

Grid lines and grid cells

Grid lines are the horizontal and vertical dividing lines that define the grid structure. Columns are numbered from left to right starting at 1, rows from top to bottom starting at 1. The spaces between lines are called grid cells.

/* style.css */
.item {
  grid-column: 1 / 3; /* spans from line 1 to line 3 (two columns) */
  grid-row: 1 / 2;    /* spans from line 1 to line 2 (one row) */
}

Lines can also be negative: -1 refers to the last line. Understanding lines is essential for precise item placement.

Grid item placement

You control where each item sits using placement properties:

  • grid-column — which columns the item occupies.
  • grid-row — which rows the item occupies.
  • grid-area — a shorthand for row-start / column-start / row-end / column-end.
/* style.css */
.header {
  grid-column: 1 / -1; /* span all columns */
  grid-row: 1;
}

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

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

Items that are not explicitly placed are auto-placed by the grid algorithm, filling cells left to right, top to bottom.

Named grid areas

grid-template-areas lets you draw your layout with strings, giving each region a name:

/* style.css */
.layout {
  display: grid;
  grid-template-columns: 250px 1fr;
  grid-template-rows: auto 1fr auto;
  grid-template-areas:
    "header  header"
    "sidebar main"
    "footer  footer";
  gap: 1rem;
}

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

This is extremely readable. You can see the layout shape directly in the CSS, and rearranging the design is as simple as rewriting the template areas string.

Grid alignment

Grid provides powerful alignment controls that work on both the container and individual items.

Container-level alignment:

/* style.css */
.grid {
  justify-items: center;  /* align items horizontally within their cell */
  align-items: center;    /* align items vertically within their cell */
  justify-content: center; /* align the grid tracks within the container */
  align-content: center;   /* align the grid tracks vertically within the container */
}

Item-level alignment:

/* style.css */
.item {
  justify-self: end;
  align-self: start;
}

These properties use the same values as Flexbox — start, end, center, stretch and others — so the learning curve is gentle if you already know Flexbox alignment.

Common CSS Grid patterns

Holy Grail layout:

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

Responsive card grid:

/* style.css */
.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 1.5rem;
}

Dashboard with fixed sidebar:

/* style.css */
.dashboard {
  display: grid;
  grid-template-columns: 260px 1fr;
  grid-template-rows: auto 1fr;
  min-height: 100vh;
}

.dashboard-header { grid-column: 1 / -1; }
.dashboard-nav    { grid-area: nav / 1 / -1 / 2; }
.dashboard-main   { grid-area: main / 2 / -1 / 3; }

Full-bleed content:

/* style.css */
.content {
  display: grid;
  grid-template-columns: 1fr min(65ch, 100%) 1fr;
}

.content > * {
  grid-column: 2; /* center text in the narrow column */
}

Responsive grids without media queries

One of Grid’s greatest strengths is building responsive layouts without media queries. The auto-fit + minmax() combination handles it:

/* style.css */
.grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 1rem;
}

As the viewport shrinks, columns collapse automatically. As it grows, new columns appear. No breakpoints needed. This pattern works for card grids, image galleries, form fields and almost any component that needs to adapt.

For more control you can layer media queries on top:

/* style.css */
.grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 1rem;
}

@media (min-width: 768px) {
  .grid {
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  }
}

When to use Grid vs Flexbox

The short answer: Grid for two dimensions, Flexbox for one.

  • Use Grid when you need items arranged in rows and columns — page layouts, dashboards, image galleries, card grids.
  • Use Flexbox when you need to align or distribute items along a single axis — navigation bars, form layouts, centering content, spacing items in a row.

In practice most projects use both. A page might use Grid for the overall layout and Flexbox for individual components within those grid areas. They complement each other, not compete.

Scenario Grid Flexbox
Page layout with header, sidebar, main and footer Yes Possible but more verbose
Navigation bar with aligned links No Yes
Responsive card grid Yes Possible but less precise
Centering a single element No Yes
Dashboard with fixed sidebar and scrollable content Yes No
Distributing space between buttons in a row No Yes

Best practices

  • Use grid-template-areas for page layouts — it makes the design readable and easy to rearrange.
  • Prefer auto-fit + minmax() for responsive component grids instead of writing media queries for every breakpoint.
  • Use gap instead of margins on grid items — it keeps spacing consistent and avoids edge gaps.
  • Name your grid areas meaningfully — header, sidebar, main — not area1, area2.
  • Combine Grid and Flexbox — Grid for the macro layout, Flexbox for micro alignment within components.
  • Avoid over-gridding — if a simple Flexbox row solves the problem, do not reach for Grid.

Common mistakes

  • Using grid for everything when Flexbox would be simpler.
  • Forgetting that gap replaces margins — double-spacing items.
  • Confusing auto-fill and auto-fit when both behave the same with minmax().
  • Not using named grid areas, leading to hard-to-maintain numeric placements.
  • Over-complicating layouts with many explicit placements when auto-placement works fine.
  • Assuming Grid is only for page layouts — it works for components too.

Is CSS Grid worth learning in 2026?

Absolutely. CSS Grid is now universally supported and has become the default tool for layout on the web. Every major framework — React, Vue, Svelte, Astro — renders HTML that gets styled with CSS, and understanding Grid means you can build any layout without fighting your tools. The days of float hacks and clearfixes are over, and developers who master Grid write cleaner, more maintainable and more responsive stylesheets. Whether you are building a simple landing page or a complex dashboard, Grid gives you the precision and flexibility that no other CSS layout method matches.

How to learn CSS Grid

A practical path:

  1. Learn display: grid, grid-template-columns and grid-template-rows.
  2. Understand the fr unit and how it distributes space.
  3. Practise auto-fit + minmax() for responsive grids.
  4. Build a Holy Grail layout with grid-template-areas.
  5. Learn item placement with grid-column and grid-row.
  6. Explore alignment properties: justify-items, align-items, justify-content, align-content.
  7. Build real projects — a dashboard, a photo gallery, a pricing page — until Grid feels natural.

From there, combine Grid with Flexbox and responsive techniques to build complete, production-ready layouts. Our interactive CSS tutorial walks you through every step with hands-on exercises.

Responsive columns

auto-fit with minmax creates as many columns as fit and collapses gracefully, with no media queries.

Prefer
.cards {
  display: grid;
  grid-template-columns:
    repeat(auto-fit, minmax(240px, 1fr));
}
Avoid
.cards {
  display: flex;
  flex-wrap: wrap;
}
.cards > * {
  width: calc(33.33% - 1rem);
}

Placing a full-width header

Grid lines make spanning trivial with 1 / -1, with no wrapper elements required.

Prefer
.header {
  grid-column: 1 / -1;
}
Avoid
<!-- a separate full-width row
     outside the grid -->

FAQ

Frequently asked questions

Keep learning

Related topics from the roadmap.

$ start learning

Ready to start learning CSS Grid?

Our interactive tutorial walks you through CSS Grid step by step — with quizzes and real code you can run in the browser.