Himanshu SharmaSoftware engineer
Let’s talk

CSS · Lesson 17 of 29

Grid basics

Build two-dimensional layouts with CSS Grid using grid-template-columns, the fr unit, gap, repeat and auto-fit for responsive card grids without media queries.

15 minLayoutUpdated 18 October 2026

By the end of this lessonCreate a grid with fixed and flexible columns, place items automatically, span items across tracks, and build a responsive card grid in one line.

Rows and columns, together

Flexbox arranges items along one line. CSS Grid arranges them in rows and columns at the same time, like a spreadsheet or newspaper layout. Where Flexbox lets content decide the layout, Grid lets you design the layout first and place content into it. It is the right tool for page layouts, galleries and anything where items in different rows should line up.

Your first grid

Put display: grid on the parent and describe the columns:

html
<style>
  .grid {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;   /* three equal columns */
    gap: 12px;
  }
  .grid div { background: #818cf8; color: white; padding: 20px; border-radius: 8px; text-align: center; }
</style>
<div class="grid">
  <div>1</div><div>2</div><div>3</div>
  <div>4</div><div>5</div><div>6</div>
</div>

You defined the columns only; the browser creates rows automatically as items fill them left to right, top to bottom. gap is the space between rows and columns (also written row-gap and column-gap).

The fr unit

fr stands for "fraction of the free space". Grid subtracts fixed sizes and gaps first, then shares the rest:

css
grid-template-columns: 1fr 1fr 1fr;    /* three equal */
grid-template-columns: 1fr 2fr;        /* second is twice as wide */
grid-template-columns: 240px 1fr;      /* fixed sidebar, flexible main */
grid-template-columns: 200px 1fr 200px;

fr is why a sidebar layout is one line.

html
<style>
  .page { display: grid; grid-template-columns: 160px 1fr; gap: 12px; }
  .side { background: #fecaca; padding: 12px; }
  .main { background: #bbf7d0; padding: 12px; }
</style>
<div class="page">
  <aside class="side">Sidebar 160px</aside>
  <main class="main">Main content takes everything that is left.</main>
</div>

repeat() and minmax()

Typing 1fr five times is tedious. repeat(count, size) does it for you:

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

minmax(min, max) sets a track's allowed size range: at least min, at most max.

The responsive grid, no media query

Combine repeat, auto-fit and minmax for the most useful Grid recipe there is:

html
<style>
  .cards {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
    gap: 12px;
  }
  .cards div { background: #fde68a; padding: 24px; border-radius: 8px; text-align: center; }
</style>
<div class="cards">
  <div>A</div><div>B</div><div>C</div><div>D</div><div>E</div><div>F</div>
</div>

Read it as: "make as many columns as will fit, each at least 140px, and let them share the leftover space equally." Resize the preview: columns appear and disappear on their own. The result is a layout that adapts from phone to desktop with a single line and no breakpoints.

auto-fit collapses empty tracks so the items stretch; auto-fill keeps the empty tracks, leaving gaps. Start with auto-fit.

Spanning tracks

Items can take more than one cell:

html
<style>
  .grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; }
  .grid div { background: #a5b4fc; padding: 16px; border-radius: 6px; }
  .wide { grid-column: span 2; background: #f9a8d4 !important; }
  .tall { grid-row: span 2; background: #86efac !important; }
</style>
<div class="grid">
  <div class="wide">spans 2 columns</div><div>2</div><div>3</div>
  <div class="tall">spans 2 rows</div><div>5</div><div>6</div><div>7</div>
  <div>8</div><div>9</div><div>10</div>
</div>

You can also place an item by line numbers: grid-column: 1 / 3 means "from line 1 to line 3" (two columns). Lines are numbered starting at 1, and -1 is the last line.

Rows

Rows are created for you at the height of their content. To set them, use grid-template-rows, or grid-auto-rows for all the automatic ones:

css
.grid { grid-auto-rows: minmax(100px, auto); }  /* at least 100px, taller if needed */

Grid versus Flexbox

Use Grid when Use Flexbox when
You need rows and columns together You have one row or one column
The layout comes first, content fits in The content decides the sizes
Items in different rows must line up Items just need spacing and alignment

They work well together: Grid for the page, Flexbox inside the components.

Common mistakes

  • Putting display: grid on the items, not the parent.
  • Using fixed pixel columns that overflow on phones. Use fr, minmax and auto-fit.
  • Using margins between items instead of gap.
  • Forgetting box-sizing for padded items.
  • Placing every item by number when automatic placement is simpler.

Exercise

Build a gallery of eight tiles that has 3 columns of equal width on any screen at least 600px wide, but is flexible below that, using only one grid declaration and gap.

Show one possible answer
html
<style>
  .gallery { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 12px; }
  .gallery div { aspect-ratio: 1; background: #c7d2fe; border-radius: 8px; }
</style>
<div class="gallery">
  <div></div><div></div><div></div><div></div>
  <div></div><div></div><div></div><div></div>
</div>

At 600px or wider the 180px minimum fits three columns; narrower, it falls to two or one automatically.

Key points

  • display grid on a parent turns its direct children into grid items placed in rows and columns.
  • grid-template-columns defines the columns, and the fr unit shares leftover space in proportions.
  • repeat with auto-fit and minmax builds a responsive grid that needs no media queries.
  • gap sets the space between rows and columns, and items can span several tracks with grid-column.
  • Use Grid for layouts in two dimensions and Flexbox for a single row or column.

Check yourself

1. What does grid-template-columns: 1fr 2fr create?
2. Which declaration creates as many 200px-minimum columns as fit, sharing the space?
3. How do you make an item stretch across two columns?
4. When is Grid a better choice than Flexbox?

Free tools for this lesson