CSS Grid
CSS Grid Layout is a two-dimensional layout system that provides control over both rows and columns simultaneously. Unlike Flexbox which is inherently one-dimensional, Grid excels at creating complex page layouts where elements need to align across both axes.
Grid works by dividing a container into rows and columns, creating a framework of cells that child elements can be placed into. This makes it ideal for magazine-style layouts, dashboard interfaces, and responsive page structures.
| 1 | .container { |
| 2 | display: grid; |
| 3 | grid-template-columns: repeat(3, 1fr); |
| 4 | grid-template-rows: auto; |
| 5 | gap: 16px; |
| 6 | } |
The grid container is the parent element that establishes the grid formatting context. All direct children become grid items.
display: grid
| 1 | .container { |
| 2 | display: grid; /* block-level grid */ |
| 3 | display: inline-grid; /* inline-level grid */ |
| 4 | } |
grid-template-columns & grid-template-rows
Define the track list — the size and number of columns and rows in the grid.
| 1 | .container { |
| 2 | grid-template-columns: 200px 1fr 2fr; |
| 3 | grid-template-rows: 100px auto 100px; |
| 4 | gap: 16px; |
| 5 | } |
gap (grid-gap)
Shorthand for row-gap and column-gap. Creates gutters between grid items.
| 1 | .container { |
| 2 | gap: 16px; /* row and column gap */ |
| 3 | row-gap: 24px; /* vertical gap only */ |
| 4 | column-gap: 12px; /* horizontal gap only */ |
| 5 | } |
justify-items & align-items
justify-items aligns items along the row (inline) axis. align-items aligns items along the column (block) axis.
| 1 | .container { |
| 2 | justify-items: start | end | center | stretch; |
| 3 | align-items: start | end | center | stretch; |
| 4 | } |
justify-content & align-content
These properties align the entire grid within its container when the grid is smaller than the container.
| 1 | .container { |
| 2 | justify-content: start | end | center | stretch | space-around | space-between | space-evenly; |
| 3 | align-content: start | end | center | stretch | space-around | space-between | space-evenly; |
| 4 | } |
grid-auto-rows & grid-auto-flow
Control the size of implicit rows and how auto-placed items flow into the grid.
| 1 | .container { |
| 2 | grid-auto-rows: minmax(100px, auto); |
| 3 | grid-auto-flow: row | column | dense; |
| 4 | } |
Grid items support placement and alignment properties that override the container-level settings.
grid-column & grid-row
Place items on specific grid lines using grid-column and grid-row. The span keyword extends an item across multiple tracks.
| 1 | .item { |
| 2 | /* Line-based placement */ |
| 3 | grid-column: 1 / 3; /* start line 1, end line 3 */ |
| 4 | grid-row: 1 / 2; /* start line 1, end line 2 */ |
| 5 | |
| 6 | /* Span shorthand */ |
| 7 | grid-column: 1 / span 2; /* start at 1, span 2 columns */ |
| 8 | grid-row: span 2; /* span 2 rows from auto position */ |
| 9 | } |
grid-area
Shorthand for grid-row-start / grid-column-start / grid-row-end / grid-column-end. Also accepts a named area from grid-template-areas.
| 1 | .item { |
| 2 | /* grid-row-start / grid-column-start / grid-row-end / grid-column-end */ |
| 3 | grid-area: 1 / 1 / 3 / 3; |
| 4 | |
| 5 | /* Named grid area */ |
| 6 | grid-area: header; |
| 7 | } |
justify-self & align-self
Override the container's justify-items or align-items for individual items.
| 1 | .item { |
| 2 | justify-self: start | end | center | stretch; |
| 3 | align-self: start | end | center | stretch; |
| 4 | } |
order
Controls the visual order of grid items. Items with a lower order value are placed first. Default is 0.
| 1 | .item-1 { order: 3; } |
| 2 | .item-2 { order: 1; } |
| 3 | .item-3 { order: 2; } |
The grid-template-areas property lets you define named regions in the grid using an ASCII-art style layout. This makes page structure visually readable in CSS.
| 1 | .layout { |
| 2 | display: grid; |
| 3 | grid-template-columns: 200px 1fr; |
| 4 | grid-template-rows: auto 1fr auto; |
| 5 | grid-template-areas: |
| 6 | "header header" |
| 7 | "sidebar main" |
| 8 | "footer footer"; |
| 9 | gap: 16px; |
| 10 | min-height: 100vh; |
| 11 | } |
| 12 | |
| 13 | .header { grid-area: header; } |
| 14 | .sidebar { grid-area: sidebar; } |
| 15 | .main { grid-area: main; } |
| 16 | .footer { grid-area: footer; } |
Each string in grid-template-areas represents a row. Columns are defined by the space-separated names. The . character creates an empty cell.
| 1 | .layout { |
| 2 | grid-template-areas: |
| 3 | "header header header" |
| 4 | ". main sidebar" |
| 5 | "footer footer footer"; |
| 6 | } |
The fr unit distributes available space proportionally, unlike fixed units (px, rem, %) which set absolute sizes.
| 1 | .fixed { |
| 2 | grid-template-columns: 200px 200px 200px; |
| 3 | /* Always 600px total, overflows if container is smaller */ |
| 4 | } |
| 5 | |
| 6 | .flexible { |
| 7 | grid-template-columns: 1fr 2fr 1fr; |
| 8 | /* Distributes available space: 25% / 50% / 25% */ |
| 9 | } |
| 10 | |
| 11 | .mixed { |
| 12 | grid-template-columns: 250px 1fr 2fr; |
| 13 | /* 250px fixed, rest split 1:2 */ |
| 14 | } |
The repeat() function reduces repetition in track definitions. minmax() sets a size range. auto-fill and auto-fit create responsive grids without media queries.
| 1 | .grid { |
| 2 | /* repeat: shorthand for repeated tracks */ |
| 3 | grid-template-columns: repeat(4, 1fr); |
| 4 | |
| 5 | /* minmax: minimum 200px, maximum 1fr */ |
| 6 | grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); |
| 7 | |
| 8 | /* auto-fill: creates as many tracks as fit */ |
| 9 | grid-template-columns: repeat(auto-fill, 100px); |
| 10 | |
| 11 | /* auto-fit: collapses empty tracks */ |
| 12 | grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); |
| 13 | } |
| Function | Description |
|---|---|
| repeat(n, size) | Repeats a track definition n times |
| minmax(min, max) | Defines a size range between min and max |
| auto-fill | Creates as many tracks as fit in the container, even if empty |
| auto-fit | Creates tracks and collapses empty ones, allowing items to stretch |
Subgrid allows a grid item to inherit the track definitions of its parent grid. This enables child elements within a grid item to align with the parent grid's columns and rows.
| 1 | .parent { |
| 2 | display: grid; |
| 3 | grid-template-columns: repeat(3, 1fr); |
| 4 | gap: 16px; |
| 5 | } |
| 6 | |
| 7 | .child-grid { |
| 8 | grid-column: span 3; |
| 9 | display: grid; |
| 10 | grid-template-columns: subgrid; |
| 11 | gap: 8px; |
| 12 | } |
info
CSS Grid uses the Box Alignment specification. Understanding the two axes is critical for precise layout control.
| Property | Axis | Aligns | Values |
|---|---|---|---|
| justify-items | Inline (row) | Items within cells | start, end, center, stretch |
| align-items | Block (column) | Items within cells | start, end, center, stretch |
| justify-content | Inline (row) | Entire grid in container | start, end, center, stretch, space-around, space-between, space-evenly |
| align-content | Block (column) | Entire grid in container | start, end, center, stretch, space-around, space-between, space-evenly |
| place-items | Both | Shorthand | <align-items> / <justify-items> |
| place-content | Both | Shorthand | <align-content> / <justify-content> |
Combine auto-fill, minmax(), and media queries to create layouts that adapt to any screen size without rigid breakpoints for every column count.
Pattern 1: Auto-fill responsive grid
| 1 | .card-grid { |
| 2 | display: grid; |
| 3 | grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); |
| 4 | gap: 24px; |
| 5 | padding: 24px; |
| 6 | } |
Pattern 2: Holy Grail layout
| 1 | .holy-grail { |
| 2 | display: grid; |
| 3 | grid-template: auto 1fr auto / 200px 1fr 200px; |
| 4 | grid-template-areas: |
| 5 | "header header header" |
| 6 | "nav main aside" |
| 7 | "footer footer footer"; |
| 8 | min-height: 100vh; |
| 9 | gap: 0; |
| 10 | } |
Pattern 3: Asymmetric magazine layout
| 1 | .magazine { |
| 2 | display: grid; |
| 3 | grid-template-columns: 2fr 1fr 1fr; |
| 4 | grid-auto-rows: minmax(120px, auto); |
| 5 | gap: 16px; |
| 6 | } |
| 7 | |
| 8 | .featured { |
| 9 | grid-column: 1 / 2; |
| 10 | grid-row: 1 / 3; |
| 11 | } |
pro tip
| Browser | Grid | Subgrid |
|---|---|---|
| Chrome | ✓ | ✓ 117+ |
| Firefox | ✓ | ✓ 71+ |
| Safari | ✓ | ✓ 16+ |
| Edge | ✓ | ✓ 117+ |