In CSS Grid Layout, what is the difference between the explicit grid and the implicit grid?
answer
- tracks you wrote vs tracks invented
- what happens to item number ten
- the surprise row is content-sized
- auto is the default track size
- grid-auto-rows and grid-auto-columns
basics
~20 sThe explicit grid is the tracks you declare yourself with grid-template-columns, grid-template-rows or grid-template-areas. The implicit grid is the extra rows or columns the browser generates on its own when items need space outside what you declared.
solid answer
~40 sThe explicit grid is whatever you write down: the columns and rows created by `grid-template-columns`, `grid-template-rows`, and the row/column structure implied by `grid-template-areas`. If there are more items than that structure holds — or an item is placed on a line outside it — the browser does not overflow or clip them; it invents additional tracks to hold them, and those are the implicit grid. Implicit tracks default to `auto`, meaning they size to their content, which is why a row you never defined usually looks a different height from the ones you did. You control their size with `grid-auto-rows` and `grid-auto-columns`, and `grid-auto-flow` decides which axis they grow along — rows by default. Gaps apply to implicit tracks exactly as they do to explicit ones.
go deeper
Be able to say plainly that the explicit grid is what you declared and the implicit grid is what the browser added for leftover items, and name grid-auto-rows as the way to size the added rows.
Explain both triggers for implicit tracks — auto-placement overflow and an item placed past the last declared line — and why the default auto sizing makes those tracks hug their content.
Show the judgment of declaring one axis and letting the other be implicit for content of unknown length, and explain what goes wrong when a team hardcodes a row count instead.
Frame it as a contract question: which parts of a layout are a structural promise the design system owns, and which parts must stay elastic because the data volume is not yours to control.
## Two grids, one container When an element becomes `display: grid`, the browser builds a grid of tracks (a track is one row or one column) and places the container's children into cells of that grid. That grid comes from two sources, and CSS names them separately. The **explicit grid** is the part you author. Three properties define it: ```css .gallery { display: grid; grid-template-columns: 200px 200px 200px; /* 3 explicit columns */ grid-template-rows: 150px 150px; /* 2 explicit rows */ } ``` `grid-template-areas` also defines explicit tracks: each string in the value is one explicit row, and each column position in the strings is one explicit column. The **implicit grid** is everything the browser adds beyond that. The example above describes six cells. Give it ten children and the browser does not clip the last four, does not overlap them, and does not overflow them out of the box: it creates two extra rows so every item has a cell. Those two extra rows are implicit tracks. They are real tracks — they participate in gaps, alignment and sizing — but you never wrote them. ## What causes an implicit track There are two triggers, and both are worth naming in an interview. 1. **Overflowing auto-placement.** More items than explicit cells. The auto-placement machinery runs out of declared cells and extends the grid along the flow axis. 2. **Explicit placement outside the declared grid.** Even a single item can do it: ```css .grid { display: grid; grid-template-rows: 100px 100px; } .badge { grid-row: 5; } /* rows 3 and 4 are created just to reach row 5 */ ``` Here the browser must create rows 3, 4 and 5 so line 5 exists. Rows 3 and 4 are empty implicit rows, and they still take part in the gap. ## How implicit tracks get sized The initial value of both `grid-auto-rows` and `grid-auto-columns` is `auto`. An `auto` track sizes to the content inside it. That single default explains most of the confusion this topic generates: your two declared rows are exactly 150px, the third row is however tall its tallest item happens to be, and the layout looks broken even though nothing is wrong. To make them match, size them yourself: ```css .gallery { grid-template-rows: 150px 150px; grid-auto-rows: 150px; /* every generated row is 150px too */ } ``` `grid-auto-rows` accepts a list of sizes that cycles: `grid-auto-rows: 100px 200px` makes generated rows alternate 100px, 200px, 100px, and so on. It is a track-size list, not a template, so `repeat()` is not part of its grammar. ## Which axis grows `grid-auto-flow` decides where new tracks appear. Its initial value is `row`, so items flow left-to-right across the columns and new **rows** are created when they run out — which is why implicit rows are the case everyone meets first. Set `grid-auto-flow: column` and the browser fills down the rows instead and creates new **columns**, sized by `grid-auto-columns` rather than `grid-auto-rows`. ## Why the distinction matters in practice Most real grids are half explicit on purpose. You know your column structure — three cards across on desktop — but you do not know how many items the server will send. So you declare the columns and deliberately let the rows be implicit, then size them with `grid-auto-rows`: ```css .cards { display: grid; grid-template-columns: 300px 300px 300px; grid-auto-rows: minmax(180px, auto); /* at least 180px, taller if needed */ gap: 16px; } ``` That is idiomatic Grid: describe the axis you control, let the other one grow. The alternative — hardcoding `grid-template-rows` for a count you are guessing at — fails in both directions. Too few declared rows and you are back to implicit tracks anyway; too many and the empty declared rows still exist and still consume their size and their gaps, leaving visible dead space at the bottom. ## The mental model Say it as: the explicit grid is a promise about structure, the implicit grid is the browser keeping that promise elastic. Nothing in Grid ever silently drops an item; if you see a track you did not declare, the layout is telling you an item needed a home, and the fix is to size that track rather than to fight its existence.
- If the browser invents tracks for me anyway, why bother declaring any rows at all?Because declared rows are a guarantee and implicit rows are a consequence. Declaring rows lets you fix a header/body/footer structure, name areas across them, and reference their lines. Implicit rows exist only when something needs them, so you cannot rely on a specific implicit row being there. The usual split is to declare the axis you control and let the other grow implicitly.
- Do gap and alignment properties apply to implicit tracks the same way?Yes. Implicit tracks are ordinary tracks once created, so `gap` is applied between them exactly as between explicit ones, and item alignment inside their cells works normally. The only things scoped to the explicit grid are its named areas and its line numbering conventions.
- Can an empty implicit track exist?Yes, when an item is explicitly placed past the end of the grid. Placing something on row 5 in a two-row grid forces rows 3 and 4 into existence so that line 5 exists; they hold nothing but still take their size from `grid-auto-rows` and still contribute a gap on each side.
saying these in an interview costs you the question
- Thinks extra items simply overflow or get clipped
- Believes grid-template-rows caps how many rows can exist
- Assumes implicit rows copy the explicit rows' sizes
- Confuses grid-auto-rows with grid-template-rows
- Thinks gap is skipped between implicit tracks