skip to content

Grid Layout

Two-dimensional layout where you declare rows and columns up front and place items into them. Grid questions probe whether you can size tracks declaratively with fr, minmax, and repeat instead of pixel-hacking — and whether you know when grid beats flex.

part ofCSSoverview, primer and where to startread it →
on this pageshow

explore

questions

29

On a CSS Grid container, which single declaration centers every grid item both horizontally and vertically inside its own cell, and what two properties does it expand to?

level: juniorimportance: must knowfreq 66%

answer

  1. one shorthand, two axes
  2. block axis value comes first
  3. A before J, alphabetical
  4. items inside cells, not tracks in container
  5. the three-line center-anything pattern

basics

~10 s

place-items: center centers every grid item in both axes of its cell. It is the shorthand for align-items (block axis) then justify-items (inline axis), so it expands to align-items: center; justify-items: center.

solid answer

~40 s

`place-items: center` on the grid container. It is the shorthand for `align-items` and `justify-items`, always written block axis first, inline axis second, and a single value is copied to both. `align-items: center` centers each item vertically inside its row track; `justify-items: center` centers it horizontally inside its column track. Because it sits on the container it applies to every item, and any individual item can opt out with `align-self`, `justify-self`, or the `place-self` shorthand. This is the whole of the classic "center anything" pattern — `display: grid; min-height: 100vh; place-items: center`. Note the distinction it hides: `place-items` centers items *inside their cells*, while `place-content` centers the whole group of *tracks* inside a larger container.

code

css · 10 lines
css
.grid {
  display: grid;
  grid-template-columns: repeat(3, 120px);
  min-height: 300px;
  place-items: center; /* align-items: center; justify-items: center */
}

.grid .logo {
  place-self: start end; /* align-self: start; justify-self: end */
}

go deeper

for a junior

Memorise that place-items: center is the one-line way to center grid items in both directions, and that it is align-items plus justify-items in that order.

for a middle

Be ready to explain why the block-axis value comes first, that the initial normal behaves as stretch, and how place-self overrides the container default for a single item.

for a senior

Show you reach for the grid centering pattern instead of absolute-position or transform hacks, and that you can say precisely when place-content rather than place-items is the property you actually want.

for a principal

Frame it as a house convention: pick one canonical centering primitive, encode it in the design system's layout utilities, and keep ad-hoc transform-based centering out of the codebase.

## The two axes a grid aligns along A grid container has an inline axis (the direction text runs — horizontal in a normal left-to-right, top-to-bottom writing mode) and a block axis (the direction blocks stack — vertical in that same mode). Every grid alignment property belongs to exactly one of them: the `justify-*` family works on the **inline** axis, the `align-*` family works on the **block** axis. That single mapping is what you need to memorise; everything else follows. The spec says inline/block rather than horizontal/vertical because in a vertical writing mode the two swap, and the properties follow the writing mode rather than the screen. ## What place-items expands to `place-items` is a shorthand for exactly two properties, in this order: `align-items` first, `justify-items` second — block axis, then inline axis. ```css .grid { place-items: center; } /* align-items: center; justify-items: center */ .grid { place-items: end start; } /* align-items: end; justify-items: start */ ``` One value is copied into both axes; two values are read block-then-inline. Every `place-*` shorthand in CSS Box Alignment uses the same order — `place-content` is `align-content justify-content`, `place-self` is `align-self justify-self`. The mnemonic that survives interview pressure: **A before J**, alphabetical. ## What "inside its cell" means `align-items` and `justify-items` position each item inside the grid area it was placed into. Their initial value is `normal`, which for a grid item behaves as `stretch`: the item's box grows to fill the area in that axis. That is why an empty `<div>` in a grid cell appears to fill the cell even though you never gave it a width or height. The moment you write `center` (or `start` / `end`), stretching stops: the item shrinks back to its content size and is positioned at the requested point in the area. ## Overriding one item The container-level properties set a default for all items. An item overrides its own alignment with the `*-self` versions: ```css .grid { display: grid; place-items: center; } .grid .logo { place-self: start end; } /* align-self: start; justify-self: end */ ``` `place-self`, `align-self`, and `justify-self` are set on the **item**, not the container — putting `place-self` on the grid container aligns the container inside *its* parent, which is a common and confusing typo. ## place-items vs place-content This is the distinction that separates people who know Grid from people who know only Flexbox. `place-items` (i.e. `align-items` + `justify-items`) moves each **item within its track**. `place-content` (i.e. `align-content` + `justify-content`) moves **the tracks themselves within the container**, and only has anything to work with when the tracks are smaller than the container. If your columns are `1fr 1fr`, the tracks already consume all the free space, so `place-content` has no visible effect while `place-items` still works fine. ## The centering pattern ```css .page { display: grid; min-height: 100vh; place-items: center; } ``` Three declarations, no transforms, no absolute positioning, no known dimensions. With a single auto-sized item, `place-content: center` happens to land on the same pixels — the single implicit track shrinks to the item and is then centered — but the mechanisms differ, and they diverge as soon as there is more than one item or the tracks are sized. ## The Flexbox caveat `justify-items` has no effect in a flex container: flex distributes items along the main axis with `justify-content`, so there is no per-item inline alignment to set. That means `place-items: center` on a flex container effectively sets only `align-items: center`. In a grid container both halves do real work, which is exactly why the shorthand is worth reaching for here. ## Common mistakes Reaching for `text-align: center` (it centers inline content *inside* the item, not the item inside its cell); writing the two values inline-first; expecting `vertical-align` to do anything to a grid item (it does not — it is for inline-level and table-cell content); and setting `place-items` on the item instead of `place-self`.

  • If you set place-items: center, what happens to the default stretching of grid items?
    It stops in both axes. The initial value `normal` behaves as `stretch` for grid items, so they fill their area. `center` is not a stretch value, so each item shrinks back to its content size (its intrinsic width and height) and is then positioned in the middle of its grid area. You often notice this as backgrounds and borders suddenly hugging the text.
  • What is the difference between place-items: center and place-content: center on a grid container?
    `place-items` aligns each item inside its own grid area; `place-content` aligns the whole set of tracks inside the grid container, and only does anything when the tracks are collectively smaller than the container. With `grid-template-columns: 1fr 1fr` the tracks already fill the width, so `place-content` is invisible while `place-items` still centers each item in its column.
  • How would you center only one item of a grid without touching the others?
    Set `place-self: center` on that item. The `*-self` properties are set on the grid item and override whatever the container's `place-items` established, for that item only. Setting `place-items` on the item does nothing useful — it would only affect that element's own children if it were itself a grid container.

saying these in an interview costs you the question

  • Says text-align: center centers the item in its cell
  • Reads place-items values inline-axis first
  • Confuses place-items with place-content
  • Puts place-self on the container instead of the item
  • Thinks vertical-align: middle works on grid items

context

open as a page

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%

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.

open as a page

In CSS Grid Layout, what is the difference between the explicit grid and the implicit grid?

level: juniorimportance: must knowfreq 70%

basics

~20 s

The 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.

open as a page

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?

level: juniorimportance: must knowfreq 72%

basics

~20 s

They 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.

open as a page

In CSS Grid, what does the track size minmax(200px, 1fr) mean when used in grid-template-columns?

level: juniorimportance: must knowfreq 60%

basics

~20 s

minmax(200px, 1fr) gives a grid column a 200px floor and a flexible ceiling: the track is never narrower than 200px, but it grows beyond that to absorb its share of the container's leftover free space.

open as a page

In a CSS Grid container, what is the difference between justify-items and justify-content?

level: middleimportance: must knowfreq 74%

basics

~20 s

justify-items aligns each grid item inside its own column track along the inline axis. justify-content distributes the column tracks themselves inside the grid container, and only does anything when the tracks are narrower than the container.

open as a page

In a three-column CSS Grid, an auto-placed item that declares grid-column: span 2 leaves an empty cell behind it. Why does the default auto-placement produce that hole?

level: middleimportance: must knowfreq 58%

basics

~20 s

The auto-placement cursor never moves backwards in the default sparse packing mode. When the wide item does not fit in the columns remaining on the current row, the cursor jumps to the next row and the skipped cells are left empty forever.

open as a page

A CSS grid sets three 200px columns and grid-template-rows: 100px 100px, but nine items are placed in it. The third row hugs its content instead of being 100px tall — why, and which property fixes it?

level: middleimportance: must knowfreq 60%

basics

~20 s

The third row is implicit: grid-template-rows declared only two, so the browser created the third to hold the overflow. Implicit tracks default to grid-auto-rows: auto, which sizes to content. Set grid-auto-rows: 100px to fix it.

open as a page

How does `grid-template-areas` place items in a CSS grid, and what makes an areas declaration invalid?

level: middleimportance: must knowfreq 68%

basics

~20 s

Each string in grid-template-areas is a row and each token in it is a cell, so the value reads like a picture of the layout. An item is placed by matching grid-area to a name. Every named area must form one solid rectangle and every row must have the same number of cells, or the whole declaration is dropped.

open as a page

Explain what grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)) does, and how the layout changes if auto-fit is replaced with auto-fill.

level: middleimportance: must knowfreq 80%

basics

~20 s

It builds a responsive grid with no media queries: the browser fits as many 200px-minimum columns as the container allows and stretches them to share the leftover space. auto-fit collapses tracks left empty, so few items stretch across the full width; auto-fill keeps those empty tracks, so items stay at their column width.

open as a page

In CSS Grid, how does the fr unit differ from a percentage track size such as 33.333% in grid-template-columns?

level: middleimportance: must knowfreq 72%

basics

~20 s

The fr unit is a share of the leftover free space, computed after fixed tracks, gaps and content minimums are taken out, while a percentage is a share of the container's full content-box width and ignores gaps entirely — which is why percentage columns plus a gap overflow.

open as a page

A CSS Grid with grid-template-columns: 1fr 1fr holds a long unbreakable string in one cell, and that column grows past its half, overflowing the container. Why does 1fr not keep the columns equal, and how do you fix it?

level: seniorimportance: must knowfreq 58%

basics

~20 s

A bare 1fr is shorthand for minmax(auto, 1fr), and that auto minimum resolves to the content's minimum size, so a track cannot shrink below the longest unbreakable word. Fix it with minmax(0, 1fr) on the track, or min-width: 0 (or an overflow value other than visible) on the item.

open as a page

Inside a CSS Grid, what does setting `margin-left: auto` on a grid item do, and how does it interact with `justify-self`?

level: middleimportance: should knowfreq 38%

basics

~20 s

An auto margin absorbs the positive free space in the item's grid area before box alignment runs, so margin-left: auto pushes the item to the inline-end edge of its area and makes justify-self in that axis have no visible effect.

open as a page

Grid items fill their cell by default. What is the initial value of align-items on a grid container, and what stops an individual item from stretching?

level: middleimportance: should knowfreq 55%

basics

~20 s

The initial value is normal, which for grid items behaves as stretch. Stretching only happens when the item's size in that axis is auto and neither margin in that axis is auto, so a set height, an auto margin, or any align-self value other than stretch cancels it.

open as a page

What does grid-auto-flow: column change about a CSS grid compared with its default value?

level: middleimportance: should knowfreq 42%

basics

~20 s

It switches the axis the grid grows along. With the default row value, items fill across the columns and extra items create new implicit rows sized by grid-auto-rows; with column, items fill down the rows and extra items create new implicit columns sized by grid-auto-columns.

open as a page

What is the value order of the CSS `grid-area` shorthand when given four line values, and how does that order differ from margin's four-value shorthand?

level: middleimportance: should knowfreq 42%

basics

~20 s

grid-area takes row-start / column-start / row-end / column-end — effectively top, left, bottom, right. Margin's four values run clockwise from the top: top, right, bottom, left. The two orders differ, which is why grid-area's is so often written wrong.

open as a page

What does `grid-column: 1 / -1` do to a CSS Grid item, and in which case does the -1 fail to reach the last visible column?

level: middleimportance: should knowfreq 55%

basics

~20 s

Negative grid line numbers count backwards from the end of the explicit grid, so -1 is its last line. The item therefore stretches across every explicit column. Tracks created implicitly beyond the template are not counted, so -1 stops short of them.

open as a page

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?

level: middleimportance: should knowfreq 50%

basics

~20 s

2 / 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.

open as a page

When a CSS grid uses `grid-template-columns: subgrid`, what does it inherit from the parent grid besides the track sizes, and what can it still override?

level: middleimportance: should knowfreq 35%

basics

~20 s

A subgrid inherits the parent's gutters and its line names on the subgridded axis, in addition to the track sizes. It can override the gutters with its own gap and add extra line names of its own, and the other axis stays fully independent.

open as a page

In CSS Grid, what does `grid-template-columns: subgrid` do, and how does it differ from giving a nested grid its own column tracks?

level: middleimportance: should knowfreq 50%

basics

~20 s

subgrid makes a nested grid reuse its parent's tracks across the area the item spans, so its own children align to the parent's grid lines. An independent nested grid defines fresh tracks that align to nothing outside itself.

open as a page

In CSS Grid, how do the track sizes min-content, max-content, and fit-content(400px) differ when used in grid-template-columns?

level: middleimportance: should knowfreq 38%

basics

~20 s

min-content sizes a column to the narrowest width its content can take when it wraps as hard as possible; max-content sizes it to the content laid out on one line with no wrapping; fit-content(400px) behaves like max-content but is capped at 400px, wrapping beyond that.

open as a page

In CSS Grid, when is grid-auto-flow: dense the right choice, and what cost do you accept by using it?

level: seniorimportance: should knowfreq 44%

basics

~20 s

Dense packing backfills the holes that spanning items leave, so use it only where item order carries no meaning — decorative or self-describing tiles. The cost is that visual order stops matching DOM order, while reading order and Tab order still follow the DOM.

open as a page

For a CSS grid rendering a list whose length comes from an API, would you declare the rows with grid-template-rows or let the implicit grid create them, and what breaks with the wrong choice?

level: seniorimportance: should knowfreq 35%

basics

~20 s

Declare only the axis you control — usually the columns — and let the rows be implicit, sizing them with grid-auto-rows. Declaring a row count guesses at the data: too few rows and implicit ones appear anyway with a different size, too many and the empty declared rows still occupy space and gaps.

open as a page

Three sibling cards sit in one CSS grid row, each with a title, a body and a footer of different lengths, and the three footers must line up horizontally. How do you build that with subgrid?

level: seniorimportance: should knowfreq 42%

basics

~20 s

Give the outer grid three row tracks for title, body and footer, make every card span all three with grid-row: span 3, and set grid-template-rows: subgrid on the card. All three cards then share the same row lines, so titles, bodies and footers align across them.

open as a page

A CSS Grid has grid-template-columns: 1fr 1fr, and one auto-placed item declares grid-column: span 3. What does the browser do?

level: middleimportance: nice to knowfreq 34%

basics

~20 s

The grid widens: before placing anything, auto-placement expands the implicit grid to fit the largest column span among auto-placed items, so a third column is created and the item spans all three. The span is never clamped to the two explicit columns.

open as a page

What does the CSS grid shorthand property set, and which longhands does it reset that you cannot even specify in it?

level: middleimportance: nice to knowfreq 24%

basics

~20 s

The grid shorthand sets grid-template-rows, grid-template-columns and grid-template-areas plus grid-auto-rows, grid-auto-columns and grid-auto-flow. Any of those six it does not mention are reset to their initial values, including the three implicit-grid longhands the template form cannot express.

open as a page

In a CSS Grid, why can `align-content: center` make part of the content permanently unreachable, and what does the `safe` keyword change?

level: seniorimportance: nice to knowfreq 28%

basics

~20 s

Centering splits any overflow evenly on both sides, and overflow past the start edge of a scroll container cannot be scrolled to, so that part is lost. align-content: safe center tells the browser to fall back to start alignment whenever the tracks overflow, keeping everything reachable.

open as a page

Given `grid-template-areas: "header header" "sidebar main";` on a CSS grid container, what line names does the browser create automatically, and how can an item use them?

level: seniorimportance: nice to knowfreq 24%

basics

~20 s

Every named area generates four lines: for main, the names main-start and main-end on both the row and column axes. An item can target them directly, so grid-column: main-start / main-end works — and grid-area: main is simply shorthand for using all four.

open as a page

Your team wants to use `subgrid` for card alignment in a shared component library, but the support matrix still includes browsers without it. How would you approach adopting it?

level: principalimportance: nice to knowfreq 22%

basics

~20 s

Ship a layout that is already acceptable without subgrid, then upgrade inside @supports (grid-template-columns: subgrid). Subgrid buys alignment refinement, not function, so the fallback should look deliberate rather than broken, and the upgrade should add rules instead of duplicating the layout.

open as a page