Day 9: CSS Grid 1: Rows, Columns & Gaps
✅ Today you will learn
- Grid container, tracks, lines, cells and areas
- grid-template-columns / rows with fr and repeat()
- gap, alignment with justify-items / align-items / place-items
- Placing items: grid-column, grid-row, span
- repeat(auto-fit, minmax()) – responsive without media queries
🏢 In the real world
A photographer client wants her portfolio gallery to show 4 photos per row on a laptop, 2 on a tablet and 1 on a phone, with every photo the same size and no gaps going wrong. With Flexbox that takes careful maths; with Grid it is a single line of CSS. Grid is how dashboards, galleries and whole page layouts are built today.
Grid in one picture
<style>
.grid > div { background: #264de4; color: #fff; padding: 12px; border-radius: 8px; font: 600 13px system-ui; }
.grid {
display: grid;
grid-template-columns: 1fr 1fr 1fr; /* 3 equal columns */
gap: 10px;
}
</style>
<div class="grid"><div>1</div><div>2</div><div>3</div><div>4</div><div>5</div><div>6</div></div>| Term | Meaning |
|---|---|
| Grid container | The element with display: grid |
| Track | One row or one column |
| Line | The numbered dividers between tracks (start at 1) |
| Cell | One square where a row and column cross |
| Area | A rectangle of one or more cells |
| fr | A fraction of the free space |
Defining columns and rows
<style>
.grid > div { background: #264de4; color: #fff; padding: 12px; border-radius: 8px; font: 600 13px system-ui; }
.grid { display: grid; gap: 8px; margin-bottom: 10px; }
.a { grid-template-columns: 200px 1fr; } /* fixed sidebar + fluid */
.b { grid-template-columns: 1fr 2fr 1fr; } /* middle twice as wide */
.c { grid-template-columns: repeat(4, 1fr); } /* 4 equal */
.d { grid-template-columns: repeat(3, 1fr); grid-template-rows: 60px 100px; }
</style>
<div class="grid a"><div>200px</div><div>1fr</div></div>
<div class="grid b"><div>1fr</div><div>2fr</div><div>1fr</div></div>
<div class="grid c"><div>1</div><div>2</div><div>3</div><div>4</div></div>
<div class="grid d"><div>row 60px</div><div>row 60px</div><div>row 60px</div><div>row 100px</div><div>row 100px</div><div>row 100px</div></div>fr divides the space LEFT AFTER gaps and fixed tracks, so 1fr 1fr 1fr with gap: 20px fits perfectly. 33.33% columns plus gaps overflow – a frequent Flexbox-era bug.
Placing items with lines and span
<style>
.grid > div { background: #264de4; color: #fff; padding: 12px; border-radius: 8px; font: 600 13px system-ui; }
.grid { display: grid; grid-template-columns: repeat(4, 1fr); grid-auto-rows: 70px; gap: 8px; }
.grid > .big { grid-column: 1 / 3; grid-row: 1 / 3; background: #c2410c; } /* lines 1→3 */
.grid > .wide { grid-column: span 2; background: #0891b2; } /* 2 columns */
.grid > .tall { grid-row: span 2; background: #16a34a; }
.grid > .full { grid-column: 1 / -1; background: #111827; } /* edge to edge */
</style>
<div class="grid">
<div class="big">big: column 1/3, row 1/3</div><div>2</div><div class="tall">tall: span 2 rows</div>
<div>4</div><div class="wide">wide: span 2</div><div>6</div>
<div class="full">full: 1 / -1</div>
</div>| Property | Example | Meaning |
|---|---|---|
| grid-column | 1 / 3 | From line 1 to line 3 (2 columns) |
| grid-column | span 2 | Take 2 columns from wherever it lands |
| grid-column | 1 / -1 | First to last line = full width |
| grid-auto-rows | minmax(120px, auto) | Height of rows created automatically |
| grid-auto-flow | dense | Back-fill holes left by big items |
Aligning inside cells
<style>
.grid { display: grid; grid-template-columns: repeat(3, 1fr); grid-auto-rows: 90px; gap: 8px; background: #eef2ff; padding: 8px; border-radius: 10px; }
.grid div { background: #264de4; color: #fff; padding: 6px 10px; border-radius: 6px; font: 600 12px system-ui; }
.c1 { justify-self: start; align-self: start; }
.c2 { place-self: center; } /* align-self + justify-self */
.c3 { justify-self: end; align-self: end; }
</style>
<div class="grid"><div class="c1">start / start</div><div class="c2">place-self: center</div><div class="c3">end / end</div></div>The magic line: auto-fit + minmax()
<style>
.gallery {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
gap: 10px;
}
.gallery img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; border-radius: 10px; display: block; }
</style>
<div class="gallery">
<img src="images/kaju-katli-400.webp" alt="Kaju katli">
<img src="images/ghewar-400.webp" alt="Ghewar">
<img src="images/rasmalai-400.webp" alt="Rasmalai">
<img src="images/ladoo-400.webp" alt="Ladoo">
<img src="images/kaju-katli-400.webp" alt="Kaju katli box">
<img src="images/ghewar-400.webp" alt="Ghewar platter">
</div>With few items, auto-fit stretches them to fill the row; auto-fill keeps empty “ghost” columns so items stay card-sized. Use auto-fill for product grids that should not balloon when only 2 products exist.
Photos of different shapes become uniform: aspect-ratio fixes the box, object-fit: cover fills it and crops the extra – like background-size: cover, but for <img>.
🏅 Job skills unlocked today
Practice tasks
🏋️ Practice – do it yourself
Show solution
Quick quiz
🧠 Quick Quiz – test yourself
Interview corner
💼 Interview Corner
Explain repeat(auto-fit, minmax(200px, 1fr)).
It creates as many columns as can fit, each at least 200px and at most an equal share of the free space. As the container narrows, columns drop to new rows automatically; auto-fit collapses empty tracks so items stretch.
What is the fr unit?
A flexible length representing a fraction of the leftover space in the grid container after fixed tracks and gaps are subtracted.
Summary
- display: grid + grid-template-columns defines the layout.
- fr shares free space; repeat() avoids repetition; gap spaces items.
- grid-column: 1 / 3 or span 2 places items; 1 / -1 = full width.
- repeat(auto-fit, minmax(x, 1fr)) = responsive grid in one line.
Day 10: grid-template-areas – full page layouts and an admin dashboard that rearrange on mobile.
