CSS Grid lays content out in two dimensions: rows and columns at the same time. Photo galleries, dashboards, card grids and complete page layouts are where Grid works best.
If Flexbox is a queue of people standing in one line, Grid is a chessboard. You describe the rows and columns once on the parent, and the children slot into the cells. That makes complex layouts surprisingly short to write, and easy to rearrange for different screen sizes.
Grid is supported by every modern browser, so you can use it on real projects today.
Defining grid columns
.grid {
display: grid;
grid-template-columns: 200px 1fr 1fr;
gap: 16px;
}display: gridmakes the parent a grid container.grid-template-columnslists the width of each column. The children fill the cells from left to right, then wrap onto new rows automatically.gapsets the space between rows and columns.
You can define rows the same way with grid-template-rows, but you often don't need to. Rows are created automatically and grow to fit their content.
The fr unit
fr means "a fraction of the available space". With 1fr 2fr, the second column is twice as wide as the first. repeat(3, 1fr) creates three equal columns without typing 1fr three times.
fr works like flex-grow in Flexbox, but for grid columns and rows. It shares out whatever space is left after fixed sizes, such as the 200px column above, have been taken.
Responsive grids without media queries
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));Read it as: "Make as many columns as will fit, each at least 200px wide, and share any leftover space between them." On a phone you get one column; on a laptop you might get four. This single line powers a huge number of card layouts on the web, including the course cards on this site.
Placing and spanning grid items
grid-column: span 2makes an item two columns wide.grid-column: 1 / -1stretches an item from the first grid line to the last, making it full width.grid-row: span 2makes an item two rows tall.
Spanning is how you create a larger "featured" tile in a gallery or a banner that runs across the top of a card grid.
Page layouts with named grid areas
For page layouts, you can name areas and draw the layout as text:
.page {
display: grid;
grid-template-columns: 200px 1fr;
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
}
header { grid-area: header; }The layout is readable at a glance, and changing it for phones is as simple as redrawing the areas inside a media query.
CSS Grid Syntax
Grid essentials
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: auto;
gap: 1rem;
place-items: center;
}
.wide { grid-column: span 2; }CSS Grid Summary
- CSS Grid arranges items in rows and columns at the same time.
grid-template-columnsdefines the columns; rows are created automatically.frshares available space, andrepeat()avoids repeating values.repeat(auto-fit, minmax(200px, 1fr))creates a responsive grid with no media queries.- Use
spanto make items larger andgrid-template-areasfor page layouts.
CSS Grid Examples
Each example runs in the page. Edit the code and press Run to see what changes.
A simple 3-column 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: 1fr 2fr 1fr;
gap: 10px;
}
.grid div {
padding: 20px;
background: #e1e6ff;
border: 2px solid #4467ff;
border-radius: 8px;
font: bold 18px sans-serif;
text-align: center;
}Line-by-line explanation
- Line 2Turn on Grid.
- Line 3Three columns; the middle one gets twice the available space.
- Line 410px between all rows and columns.
Responsive photo gallery
No media queries are needed. Resize the result to see the number of columns change.
<div class="gallery">
<img src="https://picsum.photos/id/10/300/200" alt="Forest">
<img src="https://picsum.photos/id/11/300/200" alt="Lake">
<img src="https://picsum.photos/id/12/300/200" alt="Beach">
<img src="https://picsum.photos/id/13/300/200" alt="Coast">
<img src="https://picsum.photos/id/14/300/200" alt="Sea">
<img src="https://picsum.photos/id/15/300/200" alt="River">
</div>.gallery {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
gap: 8px;
}
.gallery img {
width: 100%;
height: 110px;
object-fit: cover;
border-radius: 10px;
}
.gallery img:first-child {
grid-column: span 2;
grid-row: span 2;
height: 100%;
}Line-by-line explanation
- Line 3As many columns as fit, each at least 140px.
- Line 10
object-fit: covercrops photos neatly to fill their cells. - Lines 14 to 18The first photo spans 2 columns and 2 rows, creating a "featured" tile.
A page layout with named areas
<div class="page">
<header>Header</header>
<aside>Sidebar</aside>
<main>Main content</main>
<footer>Footer</footer>
</div>.page {
display: grid;
grid-template-columns: 140px 1fr;
grid-template-rows: auto 160px auto;
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
gap: 8px;
font: bold 15px sans-serif;
}
header { grid-area: header; background: #ffd23f; }
aside { grid-area: sidebar; background: #d6f4e4; }
main { grid-area: main; background: #e1e6ff; }
footer { grid-area: footer; background: #ffe3d7; }
.page > * { padding: 12px; border-radius: 8px; }Line-by-line explanation
- Lines 3 to 4Two columns and three rows.
- Lines 5 to 8The layout drawn as text. Each word is an area name.
- Lines 13 to 16Each element claims its area by name.
Common CSS Grid Mistakes
Forgetting display: grid
.cards { grid-template-columns: repeat(3, 1fr); }.cards { display: grid; grid-template-columns: repeat(3, 1fr); }Grid properties do nothing until the container is a grid.
Fixed columns that break on phones
.cards { display: grid; grid-template-columns: 300px 300px 300px; }.cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); }Three 300px columns need 900px, so on a phone they overflow the screen.
CSS Grid in Real Projects
Grid powers modern layouts
Dashboards (Notion, analytics tools), image galleries (Unsplash, Pinterest-style grids), product listings, magazine layouts, and the main layout of many apps use CSS Grid. The lesson page you're reading is a grid: sidebar, content and table of contents.
CSS Grid Exercises
Answer each one and check it instantly. If you get stuck, open the hint before the answer.
Create three equal columns with a 20px gap.
.grid {
display: ;
grid-template-columns: repeat(3, );
: 20px;
}
repeat(3, 1fr) makes three equal columns; gap spaces them.What does 1fr mean?
Which makes an item stretch across every column?
How many columns appear in a 700px-wide container?
.g { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 0; }
The dashboard should have a sidebar 120px wide and a main area taking the rest, with 10px gap. Fix the CSS.
<div class="dash">
<nav>Menu</nav>
<section>Stats</section>
</div>.dash {
grid-template-columns: 120 fr;
gap: 10px;
}
.dash > * { background: #e1e6ff; padding: 10px; }- Dash is a grid
- Sidebar is 120px wide
- Main area fills the rest
- 10px gap
CSS Grid Quiz
3 questions to check what you learned.
Grid is designed for layouts in…
- two dimensions (rows and columns)
- one dimension
- three dimensions
- text only
What does
grid-column: span 2do?- Moves the item to column 2
- Adds 2 columns to the grid
- Makes the item two columns wide
- Creates a 2px gap
What does
minmax(200px, 1fr)mean?- Exactly 200px
- Between 1px and 200px
- 200 columns
- At least 200px, at most one fraction of available space
CSS Grid Challenge
Build a card grid
Make .cards:
- A grid with
repeat(auto-fit, minmax(150px, 1fr))columns - A
gapof16px - Make the
.widecard span the full row (grid-column: 1 / -1)
<div class="cards">
<div class="card wide">Featured: Learn Grid in 10 minutes</div>
<div class="card">Flexbox</div>
<div class="card">Units</div>
<div class="card">Colors</div>
</div>.card { padding: 20px; background: #fff1c2; border: 2px solid #15161b; border-radius: 12px; font: 600 15px sans-serif; }
- Cards is a grid
- 16px gap
- Uses auto-fit minmax columns
- The wide card spans the full row