In CSS Grid, an item is styled `grid-column: 1 / 3`. What do the numbers 1 and 3 refer to, and how many columns does the item occupy?
answer
- fence posts, not fields
- the numbers are boundaries
- N tracks, N+1 of them
- end minus start equals tracks spanned
- 1 / 3 covers columns one and two
basics
~20 sThey are grid line numbers, not column numbers. The item starts at column line 1 and ends at column line 3, so it covers the two tracks between them — the first and second columns.
solid answer
~40 sGrid placement is expressed in **lines**, not tracks. A grid with three columns has four column lines, numbered 1 to 4 from the start edge. `grid-column: 1 / 3` is shorthand for `grid-column-start: 1` and `grid-column-end: 3`, so the item's left edge sits on line 1 and its right edge on line 3, covering the single... covering the two tracks in between: columns one and two. The end line is exclusive in the sense that the track *after* line 3 is not included. The classic mistake is reading it as "columns 1 through 3". If you give only one value, as in `grid-column: 1`, the start line is 1 and the end defaults to `auto`, which spans a single track.
code
css · 16 lines.grid {
display: grid;
grid-template-columns: 100px 100px 100px;
grid-template-rows: 50px 50px 50px;
}
/* lines 1 and 3 on the column axis: two tracks wide */
.banner {
grid-column: 1 / 3;
grid-row: 1 / 2;
}
/* one value only: end defaults to auto, so one track wide */
.badge {
grid-column: 3;
}go deeper
Know that the two values are line numbers and that the item covers the tracks between them, so 1 / 3 is two columns wide. Say plainly that lines start at 1 and that N tracks have N+1 lines.
Be ready to explain the shorthand-to-longhand mapping, what auto on either side resolves to, and why a reversed pair still works. Show the arithmetic: end minus start equals the number of tracks spanned.
Expect to debug a layout that is one track too narrow and trace it to a line-versus-track miscount. Demonstrate judgment about when hard-coded line numbers become brittle and a named line or area is the maintainable choice.
Own the convention: a codebase that mixes raw line numbers, span counts and named areas across components becomes unreadable. Argue for one placement vocabulary per layout layer and for keeping line numbers out of shared components.
## Lines are the coordinate system A grid container defined with `grid-template-columns` and `grid-template-rows` creates **tracks** (the columns and rows themselves) and, between and around them, **grid lines** — the numbered boundaries an item is anchored to. Placement properties never name a track. They name the two lines an item's edges sit on. For N tracks on an axis there are N+1 lines. Three columns means four column lines. Lines are numbered from 1 at the start edge of the explicit grid (the left edge in a left-to-right writing mode), not from 0. ```css .grid { display: grid; grid-template-columns: 100px 100px 100px; /* 3 tracks, lines 1 2 3 4 */ } ``` ## Reading grid-column and grid-row `grid-column` is the shorthand for `grid-column-start` and `grid-column-end`; `grid-row` does the same for `grid-row-start` and `grid-row-end`. The slash separates start from end: ```css .item { grid-column: 1 / 3; /* start line 1, end line 3 */ grid-row: 2 / 4; /* start line 2, end line 4 */ } ``` The item's box occupies everything between those lines. Between column line 1 and column line 3 lie exactly two tracks, so the item is two columns wide. Between row line 2 and row line 4 lie two tracks, so it is two rows tall. The arithmetic is simply `end - start = number of tracks spanned`. ## The off-by-one that trips people up The recurring bug is treating the values as track indexes: reading `1 / 3` as "columns one, two and three". That would be three tracks, and the item renders one track narrower than expected, which looks like a rendering bug but is a counting mistake. A useful mental image: the numbers are the **fence posts**, not the fields between them. Three fields need four posts, and to fence off the first two fields you point at posts 1 and 3. ## Order does not matter, but the smaller line wins the start If you write the lines in the opposite order, the grid swaps them rather than treating the declaration as an error: ```css .item { grid-column: 3 / 1; } /* behaves like 1 / 3 */ ``` This is worth knowing because it means a reversed pair silently produces a valid placement instead of failing loudly. ## Omitting one side Both halves default to `auto`. `grid-column: 1` sets the start line to 1 and leaves the end as `auto`, which resolves to a span of one track — the item is one column wide starting at line 1. Likewise `grid-column-end: 4` alone pins the right edge to line 4 and lets the start be determined automatically. `auto` on both sides is the initial state, which is why an unplaced item simply flows into the next available cell. ## Longhand versus shorthand These three blocks are equivalent: ```css .a { grid-column-start: 1; grid-column-end: 3; grid-row-start: 2; grid-row-end: 4; } .b { grid-column: 1 / 3; grid-row: 2 / 4; } .c { grid-area: 2 / 1 / 4 / 3; } ``` The `grid-area` form takes its four line values in the order row-start, column-start, row-end, column-end, which is a different order from the `grid-column` / `grid-row` pairs and a common source of confusion — prefer the explicit `grid-column` plus `grid-row` pair when clarity matters. ## Lines exist on both axes independently Column lines and row lines are separate numbering systems. Column line 2 and row line 2 have nothing to do with each other. An item is placed by choosing one pair on each axis; the intersection of those two ranges is the item's grid area. ## Why this matters beyond counting Because placement is line-based, an item can be given an area of any size at any position without touching the markup order, and two items may be pointed at the same lines, in which case they overlap in the same cells. Line numbers are also the reason spanning is expressed the way it is: once you think in lines, "start at line 2 and cover three tracks" is naturally written by pairing a line with a span count rather than doing the addition yourself. Everything else in placement — negative line numbers, named lines, area names — is a different way of *naming* a line. The underlying model stays the same: two lines per axis, and the tracks between them.
- What happens if you write the end line before the start line, as in `grid-column: 4 / 2`?The declaration is still valid. Grid swaps the two values so the smaller line becomes the start, and the item is placed from line 2 to line 4. Nothing errors and nothing is dropped, which is exactly why a reversed pair is easy to miss in review — the layout is correct but the code reads backwards.
- If a three-column grid has an item at `grid-column: 1 / 5`, what happens?Line 5 does not exist in the explicit grid, so the grid extends itself: an extra column track is generated so the item can end at line 5. The item then spans four columns, the last of which is implicit and sized by `grid-auto-columns` rather than by your template.
- Can two grid items be placed on the same lines?Yes. Placement does not reserve cells exclusively, so two items pointed at the same row and column lines occupy the same area and overlap. Which one paints on top follows the usual painting rules for positioned and stacked content, and grid items accept `z-index` without needing `position` set.
saying these in an interview costs you the question
- Says grid-column: 1 / 3 covers three columns
- Thinks the numbers are column indexes, not lines
- Believes grid lines are numbered from zero
- Assumes a reversed pair like 3 / 1 is invalid
- Thinks a single value like grid-column: 2 spans to the end