A CSS Grid item is styled `grid-column: 2 / span 3`. Which lines does it occupy, and what would `grid-column: span 3 / 6` place instead?
answer
- a count, not a coordinate
- measured from the pinned edge
- either side can carry it
- must be a positive integer
- span 2 / -1 pins to the trailing line
basics
~20 s2 / span 3 starts at column line 2 and covers three tracks, ending at line 5. span 3 / 6 ends at line 6 and counts three tracks back, starting at line 3. The span is a track count measured from the opposite edge, never a line number.
solid answer
~50 s`span <integer>` says how many tracks to cover; the other half of the value says where to measure from. In `grid-column: 2 / span 3` the start is pinned to line 2 and the span extends forward three tracks, so the end lands on line 5. In `grid-column: span 3 / 6` the end is pinned to line 6 and the span counts backwards, so the start is line 3. Either edge can carry the span, which is what makes it useful: you express "three columns wide" once and let the grid do the arithmetic, so inserting a track earlier in the template does not require re-deriving an end line. A span is always a positive count — `span 0` and negative spans are invalid — and it is the only placement value that describes size rather than position.
code
css · 13 lines.grid {
display: grid;
grid-template-columns: repeat(6, 1fr);
}
/* start pinned: line 2, three tracks forward, ends at line 5 */
.a { grid-column: 2 / span 3; }
/* end pinned: line 6, three tracks backward, starts at line 3 */
.b { grid-column: span 3 / 6; }
/* two tracks wide, flush against the last explicit line */
.c { grid-column: span 2 / -1; }go deeper
Know that span N makes an item N tracks wide and that it pairs with a line number on the other side of the slash. Be able to say what grid-column: 2 / span 2 covers.
Explain that span is a count measured from whichever edge is pinned, work the arithmetic in both directions, and note that a span with nothing pinned leaves the position to automatic placement.
Show judgment about which invariant to encode: a fixed width via span, or a fixed edge via a line. Expect to explain why a spanning item suddenly created a narrow extra track at the end of the grid.
Own the guidance for a component library: items that ship without knowing their container's template should express size with span and never hard-code line numbers, so the same component drops into grids of different widths.
## What span actually means Every placement value on an axis resolves to two lines. Numbers and names identify a line directly; `span` does not. It states a **track count**, and the grid derives the missing line by counting that many tracks away from the line the other half of the value pins down. The grammar is `span <integer>` where the integer is 1 or greater, optionally combined with a line name. `span 0` and negative counts are invalid, and an invalid placement value makes the declaration fail rather than clamping. ## Span attached to the end ```css .item { grid-column: 2 / span 3; } ``` The start is line 2. The span counts three tracks forward: columns 2, 3 and 4. The end line is therefore 5. This is identical in effect to `grid-column: 2 / 5`, but it says something different in source: the item is *three columns wide*, not *ending at line 5*. That distinction matters for maintenance. If a column is inserted before line 2 and the item's start is updated, the span form needs no other change, while the hard-coded end line has to be recomputed. ## Span attached to the start ```css .item { grid-column: span 3 / 6; } ``` Now the pinned line is the **end**, line 6, and the span counts three tracks backwards: columns 5, 4 and 3. The start line is 3. This form is the natural way to say "three tracks wide, flush against this trailing line", and it composes with negative lines: `grid-column: span 2 / -1` means "two tracks wide, ending at the last line of the explicit grid" — a right-aligned block whose width is fixed but whose position follows the template. ## Span on its own A span with nothing pinned, such as `grid-row: span 2`, fixes the item's size at two tracks and leaves both lines unresolved, so its position on that axis is decided by the grid's automatic placement rather than by the declaration. That is the usual way to say "this card is two rows tall, put it wherever it fits". ## Named lines with span The span count can also be a count of *named* lines rather than tracks. If a template names lines with `repeat(4, [col] 1fr)`, then `grid-column: col 2 / span col 2` starts at the second line named `col` and ends at the second subsequent line named `col`. This form is worth recognising in code even if you rarely write it, because `span <name>` counts occurrences of that name, not tracks — a genuinely different meaning from `span <integer>`. ```css .grid { display: grid; grid-template-columns: repeat(4, [col] 1fr) [col]; } .item { grid-column: col 2 / span col 2; } ``` ## What span is not Span is not a line number, so `grid-column: span 3` never means "start at line 3". It is not a maximum either — the item covers exactly that many tracks, and if the count reaches past the end of the explicit grid, the grid generates the tracks needed rather than clamping the item. And it is not a way to reach the end of the grid: there is no `span all`, so full-width placement is written `1 / -1`. ## Both halves as spans Writing a span on both sides, as in `grid-column: span 2 / span 3`, is legal syntax but under-specified: nothing pins a line, and the span contributed by the end half is dropped, leaving the item two tracks wide with its position resolved automatically. It is best avoided in real stylesheets because the value reads as if both numbers matter when only one does. ## Choosing between span and an explicit end line Use an explicit end line when the item's edge must align with a specific structural boundary — a sidebar that must stop exactly at the content line. Use a span when the item's *size* is the invariant — a card that is always two columns wide wherever it lands. The two forms are interchangeable arithmetically, so the choice is about which fact you want the stylesheet to state, and which one you want to survive an edit to the template.
- Is `grid-column: 2 / span 3` equivalent to `grid-column: 2 / 5`?Arithmetically yes, in a grid where those tracks exist. The difference is what the rule asserts: the span form states a width of three tracks, the line form states an edge at line 5. If the template later changes, the span form keeps the width and the line form keeps the edge — so pick the one whose invariant you actually want.
- What happens if a span reaches past the last line of the explicit grid?The grid generates the extra tracks it needs, so the item still covers the requested number of tracks. Those extra tracks are implicit and sized by `grid-auto-columns` or `grid-auto-rows`, not by your template, which is often visible as a suddenly narrow or content-sized final track.
- Why is `span 0` invalid?A span is a count of tracks the item covers, and every grid item occupies at least one track on each axis, so zero has no meaning. Negative counts are rejected for the same reason. The value fails to parse, which drops the whole declaration rather than falling back to a span of one.
saying these in an interview costs you the question
- Reads span 3 as start at line 3
- Thinks span can only follow the slash
- Believes span clamps at the grid's edge
- Says span 0 makes an item zero tracks wide
- Assumes span all exists for full width