skip to content

In a CSS Grid container, where do grid items end up if you never set grid-column or grid-row on them?

level: juniorimportance: must knowfreq 62%

answer

  1. no coordinates needed
  2. the container decides, in DOM order
  3. one item, one cell
  4. grid-auto-flow: row is the initial value

basics

~20 s

CSS Grid auto-places any item you do not position: it walks the items in document order and drops each one into the next empty cell, one item per cell, filling row by row because grid-auto-flow defaults to row.

solid answer

~40 s

Every in-flow child of a grid container becomes a grid item, and any item without `grid-column` or `grid-row` is handled by the auto-placement algorithm. It processes items in document order, keeps a placement cursor, and puts each item into the next empty cell — moving across the row first, then dropping to the next row. That row-major direction comes from `grid-auto-flow`, whose initial value is `row`. One item occupies one cell unless it declares a span. Items you placed explicitly are positioned first, and the auto-placed ones flow around them, skipping occupied cells. If the items run past the last row you defined, the grid grows extra rows to hold them, so nothing is dropped or overlapped.

go deeper

for a junior

Be ready to say plainly that grid places unpositioned items for you: next empty cell, document order, one per cell, across the row first. Name grid-auto-flow: row as the default that sets that direction.

for a middle

Explain the placement passes — definite positions first, row-locked items next, everything else auto-placed around them — and how the cursor advances through cells rather than jumping to arbitrary gaps.

for a senior

Show that you rely on this: layouts whose item count varies should be described by tracks, not per-item coordinates, and DOM order should already be the intended reading order so the layout stays accessible for free.

for a principal

Own the tradeoff between a template that pins items to named areas and one that lets content flow. Pinning is predictable but brittle across breakpoints and content volumes; flowing is resilient but gives you less control over exactly where a given item lands.

## Auto-placement is the default, not a fallback When you write `display: grid` and define tracks, you are describing a coordinate system: a set of column lines and row lines that carve the container into cells. You *may* address a cell explicitly with `grid-column` and `grid-row`, but you almost never have to. Any grid item that does not carry a definite position is placed for you by the **auto-placement algorithm**, and in a typical card gallery or form layout that is every single item. ```css .gallery { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1rem; } ``` With that stylesheet, ten children get ten cells: three in the first row, three in the second, three in the third, one in the fourth. No child needs a rule of its own. ## What counts as a grid item Only the **direct children** of the grid container become grid items. Grandchildren are laid out inside their parent item by whatever rules apply there. Text directly inside the container is wrapped in an anonymous grid item. This matters because auto-placement operates on that flat list of children, in the order they appear in the document. ## The cursor, in plain terms The algorithm keeps a **placement cursor** — a row/column pointer that starts at the first row and first column of the grid. For each auto-placed item, in document order, it looks for the next empty area big enough for the item, places it there, and leaves the cursor just past it. Because `grid-auto-flow` defaults to `row`, the cursor advances column by column across a row before moving down to the next row. Set `grid-auto-flow: column` and the same walk happens down each column instead. Two consequences fall straight out of this: - **Document order is visual order.** Reordering the markup reorders the layout. This is why grid layouts stay accessible by default: the reading order the screen reader and the Tab key follow is the same order you see. - **Auto-placed items never overlap.** The algorithm only ever chooses empty areas. Overlap is possible in grid, but you have to ask for it with explicit placement. ## Explicit items go first The algorithm is a sequence of passes. Items with a definite position on both axes are placed first; items locked to a specific row (or column, in column flow) come next; everything else is auto-placed last, flowing around the cells that are already taken. ```css .hero { grid-column: 1 / 4; } /* placed first, occupies all of row 1 */ .card { /* auto-placed; starts on row 2 */ } ``` So you can pin one banner into a known area and let the rest of the content arrange itself around it, without giving every card coordinates. ## Spans still participate An auto-placed item can declare a size without declaring a position: `grid-column: span 2` says "two columns wide, you pick which two". The algorithm then looks for the next empty run of two columns. This is where the layout can surprise you: if the cursor sits in the last column and the next item needs two columns, that last cell stays empty and the item starts on the following row. ## Running out of rows If you defined three rows and have twelve items in a three-column grid, the fourth row does not exist in your template — the grid creates it. Those generated tracks size themselves according to `grid-auto-rows` (its initial value is `auto`, i.e. content-sized). Practically, this is why a grid whose item count changes at runtime — a search-results list, a paginated gallery — needs no extra rules: you describe the columns, and the rows appear as needed. ## What a junior should be able to say Name the default flow direction (`row`), say that items fill in document order one per cell, and note that explicitly placed items are handled first. Then show you know the escape hatches exist — `grid-auto-flow: column` to flow down instead of across, and per-item `grid-column`/`grid-row` when a specific item really must live in a specific cell.

  • Can two auto-placed grid items ever end up overlapping the same cell?
    No. The auto-placement algorithm only ever selects an empty area, so auto-placed items never overlap each other or an explicitly placed item. Overlap in grid is something you opt into by giving two items explicit `grid-column`/`grid-row` ranges that intersect — which is a legitimate technique for layering, but it is never the accidental result of auto-placement.
  • If two items both declare grid-row: 2 but no column, how are they ordered?
    They are locked to row 2 and placed in that row in document order, each taking the next free column in the row. The pass that handles row-locked items runs before general auto-placement, so those two items claim their cells first and the fully auto-placed items flow around them.
  • Does auto-placement look at anything other than document order?
    Not for ordering — it walks the items in document order. What changes the outcome is per-item placement (a definite `grid-column`/`grid-row`, or a `span`), the flow direction from `grid-auto-flow`, and the `order` property, which changes the order the algorithm sees while leaving the DOM — and therefore the reading and focus order — untouched.

saying these in an interview costs you the question

  • Thinks every grid item needs an explicit grid-column and grid-row
  • Says grid items are placed in size order rather than document order
  • Believes auto-placed items can silently overlap each other
  • Confuses grid items with all descendants instead of direct children
  • Assumes items overflowing the template are clipped or dropped

context