How Grid Places Items
When you don't explicitly place grid items, CSS Grid has a smart algorithm that automatically positions them. Understanding this algorithm helps you predict layouts and control item flow.
The Default Behavior
By default, Grid places items:
- One per cell
- Left to right (in rows)
- Top to bottom
- In source order (HTML order)
/* Simple grid - items flow left to right, top to bottom */
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 16px;
}
/* Items 1, 2, 3 in first row */
/* Items 4, 5, 6 in second row */
/* And so on... */
💡 Key Concept:
Auto-placement only affects items you haven't explicitly positioned.
If you use grid-column or grid-area, that item is "placed"
and auto-placement works around it.
grid-auto-flow: Changing Direction
Control whether Grid fills rows or columns first:
row (default)
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-flow: row; /* Default */
}
/* Result: Fills rows left to right
1 2 3
4 5 6
7 8 9 */
column
.grid {
display: grid;
grid-template-rows: repeat(3, 100px);
grid-auto-flow: column;
}
/* Result: Fills columns top to bottom
1 4 7
2 5 8
3 6 9 */
grid-auto-rows and grid-auto-columns
What happens when you have more items than defined rows/columns? Grid creates implicit tracks (rows or columns) automatically.
Controlling Implicit Row Heights
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: 100px 100px; /* Only 2 explicit rows */
grid-auto-rows: 150px; /* Any extra rows are 150px */
}
/* Result:
Row 1: 100px (explicit)
Row 2: 100px (explicit)
Row 3: 150px (implicit, auto-created)
Row 4: 150px (implicit, auto-created)
... */
Flexible Implicit Rows
grid-auto-rows: minmax(100px, auto);
Creates rows that are at least 100px but grow to fit content.
Dense Packing
When some items span multiple cells, Grid can leave gaps. The dense keyword
fills these holes by placing smaller items in them.
Without dense (default)
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-flow: row;
}
.item-wide {
grid-column: span 2; /* Spans 2 columns */
}
/* Result (with gaps):
1 1 2
3 4 4
_ 5 6 ← Gap left by item 4 */
With dense
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-flow: row dense;
}
/* Result (no gaps):
1 1 2
3 4 4
5 5 6 ← Item 5 moved up to fill gap */
⚠️ Warning:
Dense packing can change the visual order of items (they won't match HTML order). This can confuse keyboard/screen reader users. Use carefully!
Practical Examples
Pinterest-Style Masonry (Approximation)
.masonry {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
grid-auto-rows: 20px; /* Small incremental rows */
gap: 16px;
}
.item-tall {
grid-row: span 10; /* Spans 200px (10 × 20px rows) */
}
.item-medium {
grid-row: span 7; /* Spans 140px */
}
.item-short {
grid-row: span 5; /* Spans 100px */
}
Dynamic Card Grid
.cards {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
grid-auto-rows: minmax(200px, auto);
gap: 24px;
}
/* Featured cards span 2 columns */
.card.featured {
grid-column: span 2;
}
Vertical Timeline
.timeline {
display: grid;
grid-template-columns: 1fr;
grid-auto-flow: row;
grid-auto-rows: minmax(80px, auto);
gap: 16px;
}
Combining Explicit and Implicit Grids
You can define some tracks explicitly and let Grid create the rest:
.grid {
display: grid;
grid-template-columns: 200px 1fr 200px; /* 3 explicit columns */
grid-auto-rows: 100px; /* Any rows auto-created at 100px */
gap: 20px;
}
/* If you have 9 items:
- All go in the 3 defined columns
- Grid auto-creates 3 rows (each 100px tall) */
Real-World Use Case: Blog Archive
.blog-archive {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
grid-auto-rows: minmax(250px, auto);
grid-auto-flow: row dense;
gap: 32px;
}
/* Featured posts span 2 columns */
.post.featured {
grid-column: span 2;
}
/* Long posts take more vertical space */
.post.long {
grid-row: span 2;
}
Understanding the Algorithm
Grid's auto-placement follows this logic:
- Place explicitly positioned items first
- Fill remaining cells with auto-placed items
- Follow grid-auto-flow direction (row or column)
- Create implicit tracks as needed
- If using dense, backfill gaps with smaller items
✅ Pro Tip:
For most layouts, the defaults work great! Only reach for grid-auto-flow and
dense when you have a specific layout challenge.
Common Patterns
Pattern 1: Infinite Scrolling Grid
/* Automatically adds rows as content loads */
.infinite-grid {
grid-template-columns: repeat(4, 1fr);
grid-auto-rows: 200px;
}
Pattern 2: Newspaper Layout
/* Mix of different sized articles */
.newspaper {
grid-template-columns: repeat(6, 1fr);
grid-auto-rows: 100px;
grid-auto-flow: row dense;
}
Pattern 3: Vertical Feed
/* Single column, variable height items */
.feed {
grid-template-columns: 1fr;
grid-auto-rows: minmax(100px, auto);
grid-auto-flow: row;
}
Debugging Auto-Placement
If items aren't appearing where you expect:
- Check: Did you explicitly place some items? They anchor the auto-placement
- Check: Is
grid-auto-flowset to row or column? - Check: Are there enough explicit tracks or is Grid creating implicit ones?
- Check: Browser DevTools shows both explicit and implicit grid lines
You've Completed All 9 Lessons!
Congratulations! You've mastered CSS Grid from basics to advanced techniques. You now know how to create any layout imaginable with Grid.
What you've learned:
- ✅ Grid fundamentals (Lessons 1-3)
- ✅ Real-world patterns (Lessons 4-6)
- ✅ Advanced techniques (Lessons 7-9)
Keep practicing, experiment with the generator, and remember: the best way to learn Grid is to use it in real projects!