Skip to content
Happy Programming Guide
Start learning
Web Development

CSS Grid Explained

Grid lays out rows and columns at the same time. Here is the fr unit, repeat and auto-fit, named areas, and the one line that makes a responsive gallery with no media queries.

Books and a notebook on a desk

Grid lays things out in two directions at once — rows and columns together. Where flexbox arranges items along a line, grid places them into a structure you define.

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

Three equal columns, with a 20px gap. That is most of what you need.

Defining columns#

CSS
grid-template-columns: 200px 200px 200px;   /* three fixed columns */
grid-template-columns: 1fr 1fr 1fr;         /* three equal, filling the width */
grid-template-columns: repeat(3, 1fr);      /* the same, written once */
grid-template-columns: 240px 1fr;           /* fixed sidebar, flexible content */
grid-template-columns: 1fr 2fr;             /* second column twice as wide */

fr means “a fraction of the space left over”. It is better than percentages because it accounts for the gap automatically — three columns of 33.33% with a gap between them overflow; three of 1fr do not.

The responsive line worth memorising#

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

Read it as: fit as many columns as you can, each at least 240px wide, sharing the leftover space equally.

Four columns on a wide screen, two on a tablet, one on a phone — with no media queries at all. This single line replaces most of what people write breakpoints for.

auto-fill is the near-identical alternative: it keeps empty column tracks where auto-fit collapses them. With only two items in a wide container, auto-fit stretches them across; auto-fill leaves them at 240px with space to the right. auto-fit is usually what you want.

Rows#

CSS
grid-template-rows: 60px 1fr 40px;   /* header, content, footer */
grid-auto-rows: minmax(120px, auto); /* any extra rows: at least 120px */

You often do not need to define rows at all. Grid creates them as needed, sized to their content, which is usually right.

Placing items#

CSS
.featured {
  grid-column: span 2;      /* take two columns */
  grid-row: span 2;         /* and two rows */
}

.hero {
  grid-column: 1 / 4;       /* from line 1 to line 4 */
  grid-column: 1 / -1;      /* from the first line to the last — full width */
}

Grid counts the lines between tracks, not the tracks themselves, so three columns have four lines. 1 / -1 is the one to remember: full width, whatever the column count.

Named areas#

For page layouts, this is the most readable thing in CSS:

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

.page__header  { grid-area: header; }
.page__sidebar { grid-area: sidebar; }
.page__main    { grid-area: main; }
.page__footer  { grid-area: footer; }

The template is a picture of the layout. Rearranging for mobile becomes obvious:

CSS
@media (max-width: 700px) {
  .page {
    grid-template-columns: 1fr;
    grid-template-areas:
      "header"
      "main"
      "sidebar"
      "footer";
  }
}

Note the sidebar moved below the main content, and no HTML changed.

Aligning inside the grid#

CSS
.grid {
  justify-items: stretch;   /* items across their column: start | center | end */
  align-items: stretch;     /* items down their row */

  justify-content: start;   /* the whole grid horizontally, if it is narrower */
  align-content: start;     /* the whole grid vertically */
}

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

The distinction: *-items positions content inside its cell; *-content positions the whole grid inside the container.

And the shortest centring in CSS:

CSS
.centre {
  display: grid;
  place-items: center;
  min-height: 100vh;
}

Grid or flexbox?#

Use grid when Use flexbox when
You need rows and columns to align Items flow in one direction
The layout is defined up front The content decides the sizing
Page skeletons, galleries, dashboards Nav bars, button rows, card internals

They are not competitors. A very common pattern is a grid for the page and flexbox inside each cell.

Seeing what grid is doing#

Open DevTools, find the grid container in the Elements panel, and click the small grid badge next to it. The browser overlays the line numbers and track sizes on the page.

That overlay turns “why is this item in the wrong place” from guesswork into reading. See browser DevTools for beginners.

Questions people ask#

Do I still need flexbox if I know grid?

Yes. Grid is for structure; flexbox is better whenever items should size themselves and flow, like a nav bar or a row of buttons of different widths.

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

With fewer items than fit, auto-fit collapses the empty tracks so the items stretch; auto-fill keeps them, leaving a gap on the right. Use auto-fit unless you specifically want the empty columns preserved.

Can grid items overlap?

Yes — place two items in the same cell and control the stacking with z-index. Useful for text over an image.

Is grid supported everywhere?

Yes, in every current browser and for years now. It needs no fallback for ordinary use.

Why is my item not going where I told it?

Check whether you are counting tracks instead of lines — three columns have four lines. Turn on the DevTools grid overlay and the numbers become visible.

Where to go next#

Related lessonResponsive design basics

Keep reading

Keep going — pick your next guide

The fastest way to improve is to read one guide, then build the thing it describes. Start with the basics, or jump straight to a project.

Ask a question or share what worked

Your email address will not be published. Required fields are marked *