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.
.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.
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr); /* only 3 columns explicitly defined */
gap: 12px;
}<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.
.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 |
| Created automatically by the browser |
Sized by | Whatever track sizes you write ( |
|
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 |
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-columnswhenever your grid can receive a variable amount of content, so growth is predictable rather than defaulting toauto.If a layout should never grow, make every track explicit and avoid over-placing items — that keeps the implicit grid empty entirely.