CSS Grid cheat sheet
AdvertisementCSS Grid lays out content in rows and columns at the same time. It is the right tool for page layouts, galleries and dashboards, and it replaces a lot of old float and table hacks. This cheat sheet lists the properties, with values that explain themselves and patterns you can paste. The free CSS course teaches it step by step in Grid basics and Grid areas.
Vocabulary
- Grid container: the element with
display: grid. - Grid items: its direct children.
- Tracks: the rows and columns.
- Lines: the numbered boundaries between tracks (a grid with 3 columns has 4 column lines, numbered from 1).
- Cells and areas: a cell is one row-column intersection; an area is a rectangle of cells.
- Gap: the gutter between tracks.
A first grid
<div class="grid">
<div>1</div><div>2</div><div>3</div>
<div>4</div><div>5</div><div>6</div>
</div>
.grid {
display: grid;
grid-template-columns: 200px 1fr 1fr; /* three columns */
gap: 1rem;
}
The first column is 200px wide; the other two share the rest equally. Rows are created automatically as items need them.
Container properties
| Property | Example | What it does |
|---|---|---|
display |
grid / inline-grid |
Creates the grid |
grid-template-columns |
200px 1fr 2fr |
Defines column tracks |
grid-template-rows |
auto 1fr auto |
Defines row tracks |
grid-template-areas |
"head head" "side main" |
Names areas by drawing the layout |
gap (row-gap, column-gap) |
1rem 2rem |
Space between tracks |
grid-auto-rows / grid-auto-columns |
minmax(100px, auto) |
Size of automatically created tracks |
grid-auto-flow |
row / column / dense |
How items auto-place; dense fills holes |
justify-items |
start / end / center / stretch |
Aligns items inside their cell, horizontally |
align-items |
same | Aligns items inside their cell, vertically |
place-items |
center |
Shorthand for align-items and justify-items |
justify-content |
start / center / space-between ... |
Places the whole grid horizontally when it is smaller than the container |
align-content |
same | Places the whole grid vertically |
Sizing tracks
| Value | Meaning |
|---|---|
100px, 10rem, 30% |
Fixed or percentage size |
1fr |
A fraction of the free space after fixed tracks and gaps |
auto |
Sized by content (and stretches if space remains) |
min-content / max-content |
Smallest or largest the content wants |
minmax(200px, 1fr) |
At least 200px, at most one fraction |
repeat(3, 1fr) |
Three equal tracks |
repeat(auto-fit, minmax(220px, 1fr)) |
As many 220px-minimum columns as fit |
1fr 2fr makes the second column twice as wide as the first. Note that 1fr means minmax(auto, 1fr), so a track with a wide, unbreakable item can grow beyond its share; use minmax(0, 1fr) to stop that.
auto-fit and auto-fill
The responsive card grid needs no media queries:
.cards {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
gap: 1rem;
}
Each column is at least 220px. As the container widens, more columns appear; any left-over space is shared. The difference:
auto-fitcollapses empty tracks, so the items stretch to fill the row.auto-fillkeeps the empty tracks, so with few items you still see the column slots and the items stay at their size.
Use auto-fit for most card grids.
Placing items
By default items fill cells in order. You can place them with line numbers or names.
| Property | Example | What it does |
|---|---|---|
grid-column |
1 / 3 |
Starts at line 1, ends at line 3 (spans 2 columns) |
grid-column |
span 2 |
Spans 2 columns from its auto position |
grid-row |
2 / 4 |
Spans from row line 2 to 4 |
grid-area |
2 / 1 / 4 / 3 |
row-start / column-start / row-end / column-end |
grid-area |
header |
Places the item in a named area |
justify-self, align-self, place-self |
center |
Aligns one item in its cell |
order |
-1 |
Changes the order (visual only) |
Negative line numbers count from the end: grid-column: 1 / -1 spans all columns, however many there are.
Named areas: draw the page
<div class="page">
<header>Header</header>
<nav>Nav</nav>
<main>Main</main>
<aside>Aside</aside>
<footer>Footer</footer>
</div>
.page {
display: grid;
grid-template-columns: 200px 1fr 200px;
grid-template-areas:
"header header header"
"nav main aside"
"footer footer footer";
gap: 1rem;
min-height: 100vh;
grid-template-rows: auto 1fr auto;
}
header { grid-area: header; }
nav { grid-area: nav; }
main { grid-area: main; }
aside { grid-area: aside; }
footer { grid-area: footer; }
The template is a picture of the layout. Each string is a row; repeated names span cells; a dot (.) leaves a cell empty. To make it responsive, redefine the template in a media query:
@media (max-width: 700px) {
.page {
grid-template-columns: 1fr;
grid-template-areas: "header" "nav" "main" "aside" "footer";
grid-template-rows: auto;
}
}
Areas must be rectangles, and every row string needs the same number of columns.
Ready-made layouts
Holy-grail with a sticky footer: the page layout above, with grid-template-rows: auto 1fr auto so the main row takes the spare height.
Even gallery with one big feature:
.gallery { display: grid; grid-template-columns: repeat(4, 1fr); gap: .5rem; }
.gallery .feature { grid-column: span 2; grid-row: span 2; }
Centred content with side margins:
.wrap { display: grid; grid-template-columns: 1fr min(65ch, 100% - 2rem) 1fr; }
.wrap > * { grid-column: 2; }
.wrap > .full { grid-column: 1 / -1; } /* breaks out to full width */
Form with labels left and fields right:
.form { display: grid; grid-template-columns: max-content 1fr; gap: .5rem 1rem; align-items: center; }
Dead-centre one item:
.hero { display: grid; place-items: center; min-height: 60vh; }
Subgrid
A grid item that is itself a grid can use grid-template-columns: subgrid (and rows) to align its children to the parent's tracks. It is useful for cards whose titles, text and buttons should line up across a row. Support is good in current browsers, but check before depending on it.
Common mistakes
- Putting
grid-*item properties on the container, or the container properties on items. - Forgetting that only direct children are grid items. Nested elements need their own grid.
- Expecting
justify-contentto align items. It positions the grid within its container;justify-itemsaligns items in their cells. - Overflowing
1frtracks. Useminmax(0, 1fr)when content cannot shrink. - Mismatched row strings in
grid-template-areas, which makes the whole declaration invalid. - Fixed pixel columns on small screens. Prefer
fr,minmax()andauto-fit. - Using Grid for a simple row of buttons. Flexbox is easier there.
Grid or Flexbox?
Choose Grid when you think in rows and columns and want items to line up on both; choose Flexbox when you think in one direction and want content to decide sizes. Real pages use both: Grid for the page and card layouts, Flexbox inside the components.
Debugging
In the browser developer tools, click the grid badge beside the container in the Elements panel to overlay line numbers and area names. Inspect which line numbers an item uses and whether the implicit grid created extra tracks.
Keep learning
Practise with the Grid lessons and the landing-page project in the CSS course, test yourself with the CSS interview questions, and see a schedule in the 30-day HTML and CSS study plan.