CSSImplicit vs Explicit Grid

Implicit vs Explicit Grid

Every CSS Grid has two coexisting track systems: the explicit grid, which you define directly, and the implicit grid, which the browser creates on demand to hold anything that doesn't fit in the explicit one. Understanding the split explains a lot of "why did my grid grow an extra row I never asked for" moments.

The Explicit Grid

The explicit grid is whatever you declare with grid-template- columns, grid-template-rows, or grid-template-areas. These tracks exist exactly as sized, in exactly the number you wrote, regardless of how much content ends up inside the grid.

CSS
.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr); /* 3 explicit columns */
  grid-template-rows: 100px 100px;       /* 2 explicit rows */
  gap: 12px;
}
The Implicit Grid

If you place more items than the explicit grid has cells for — or explicitly place an item beyond the declared tracks — the browser automatically generates extra tracks to hold the overflow. Those extra tracks are the implicit grid. They default to auto sizing (grow to fit their content) unless you size them yourself.

CSS
.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr); /* only 3 columns explicitly defined */
  gap: 12px;
}

HTML
<div class="grid">
  <div>1</div><div>2</div><div>3</div>
  <div>4</div><div>5</div><div>6</div>
  <div>7</div><div>8</div>
</div>

With only grid-template-columns defined and no grid-template- rows, every row after the first is implicit — the browser keeps adding rows automatically as items 4 through 8 wrap onto them, sized by content since no explicit row sizing exists.

Sizing Implicit Tracks: grid-auto-rows / grid-auto-columns

grid-auto-rows and grid-auto-columns set the size for any track the browser creates implicitly — they have no effect on explicit tracks. This is how you keep auto-generated rows from being an unpredictable auto height.

CSS
.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-auto-rows: 120px; /* every implicit row is fixed at 120px */
  gap: 12px;
}

/* You can also give implicit tracks a size range */
.grid-flexible {
  grid-auto-rows: minmax(100px, auto); /* at least 100px, grows if needed */
}

/* Or alternate sizes for successive implicit tracks */
.grid-alternating {
  grid-auto-rows: 100px 150px; /* 1st implicit row 100px, 2nd 150px, repeats */
}

Aspect

Explicit grid

Implicit grid

Defined by

grid-template-columns / -rows / -areas

Created automatically by the browser

Sized by

Whatever track sizes you write (1fr, 200px, minmax(), ...)

grid-auto-rows / grid-auto-columns (defaults to auto)

Track count

Exactly as many as you declare

As many as needed to hold overflow content or out-of-range placements

Typical trigger

You wrote it yourself

More items than explicit cells, or grid-row: 6 placing beyond a smaller explicit grid

Explicit placement can also trigger implicit tracks
It's not only overflow content that creates implicit tracks — placing any item explicitly beyond the declared grid (e.g. `grid-column: 8` on a 3-column explicit grid) forces the browser to generate implicit columns up to that line too.
  • Auto-placed items (see Auto Placement & grid-auto-flow) are the most common source of implicit tracks — the grid grows to fit whatever you throw at it.

  • Set grid-auto-rows/grid-auto-columns whenever your grid can receive a variable amount of content, so growth is predictable rather than defaulting to auto.

  • If a layout should never grow, make every track explicit and avoid over-placing items — that keeps the implicit grid empty entirely.

Next
Take grid alignment across nested components to the next level: [Subgrid](/css/subgrid).