Day 10: CSS Grid 2: Template Areas & Dashboards
✅ Today you will learn
- Name areas with grid-template-areas
- Holy-grail page layout: header, nav, main, aside, footer
- Rearranging the layout for mobile by redrawing the map
- A real admin dashboard: sidebar, top bar, KPI cards, chart
- Grid + Flexbox together; subgrid
🏢 In the real world
Mr. Sharma now wants an admin panel to see today’s sales, orders and best sellers. Every Indian company – from a school ERP to a billing SaaS – has a screen like this, and front-end interviews love asking “build this dashboard layout”. You will build it today with about 30 lines of Grid.
Draw your layout with words
<style>
.page {
display: grid;
grid-template-columns: 160px 1fr 160px;
grid-template-rows: auto 1fr auto;
grid-template-areas:
"header header header"
"nav main aside"
"footer footer footer";
gap: 8px; min-height: 300px;
}
.page > * { padding: 12px; border-radius: 8px; color: #fff; font: 600 14px system-ui; }
header { grid-area: header; background: #264de4; }
nav { grid-area: nav; background: #0891b2; }
main { grid-area: main; background: #16a34a; }
aside { grid-area: aside; background: #f59e0b; }
footer { grid-area: footer; background: #111827; }
</style>
<div class="page">
<header>header</header><nav>nav</nav><main>main</main><aside>aside</aside><footer>footer</footer>
</div>Every row string must have the same number of cells; each area must be a rectangle; use a dot (.) for an empty cell. The HTML order can stay logical for screen readers while the visual layout changes.
Rearranging for mobile = redraw the map
@media (max-width: 700px) {
.page {
grid-template-columns: 1fr;
grid-template-areas:
"header"
"nav"
"main"
"aside"
"footer";
}
}Real project: the admin dashboard
<style>
* { box-sizing: border-box; }
body { margin: 0; background: #f1f5f9; }
.app {
display: grid;
grid-template-columns: 200px 1fr;
grid-template-rows: 56px 1fr;
grid-template-areas:
"side top"
"side main";
min-height: 420px;
}
.side { grid-area: side; background: #111827; color: #cbd5e1; padding: 16px; }
.side b { color: #fff; display: block; margin-bottom: 16px; }
.side a { display: block; color: inherit; text-decoration: none; padding: 8px 10px; border-radius: 8px; }
.side a.on { background: #264de4; color: #fff; }
.top { grid-area: top; background: #fff; display: flex; align-items: center; justify-content: space-between; padding: 0 16px; border-bottom: 1px solid #e5e7eb; }
.main { grid-area: main; padding: 16px; display: grid; gap: 14px; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); align-content: start; }
.kpi { background: #fff; border-radius: 12px; padding: 14px; box-shadow: 0 2px 8px rgb(0 0 0 / 5%); }
.kpi small { color: #6b7280; } .kpi b { display: block; font-size: 1.5rem; }
.kpi.up b { color: #16a34a; }
.panel { grid-column: 1 / -1; background: #fff; border-radius: 12px; padding: 14px; }
.bars { display: flex; align-items: flex-end; gap: 8px; height: 120px; }
.bars span { flex: 1; background: linear-gradient(#06b6d4, #264de4); border-radius: 6px 6px 0 0; }
@media (max-width: 600px) {
.app { grid-template-columns: 1fr; grid-template-rows: auto auto 1fr; grid-template-areas: "top" "side" "main"; }
.side { display: flex; gap: 6px; overflow-x: auto; padding: 8px; }
.side b { display: none; }
}
</style>
<div class="app">
<nav class="side"><b>🍬 Sharma Admin</b><a class="on" href="#">Dashboard</a><a href="#">Orders</a><a href="#">Products</a><a href="#">Customers</a></nav>
<header class="top"><strong>Dashboard</strong><span>Vikas ▾</span></header>
<main class="main">
<div class="kpi up"><small>Today’s sales</small><b>₹48,200</b>▲ 12%</div>
<div class="kpi"><small>Orders</small><b>63</b>9 pending</div>
<div class="kpi"><small>Kg sold</small><b>71.5</b>Kaju katli top</div>
<div class="kpi up"><small>New customers</small><b>18</b>▲ 4</div>
<section class="panel"><b>Sales – last 7 days</b>
<div class="bars"><span style="height:40%"></span><span style="height:55%"></span><span style="height:35%"></span><span style="height:70%"></span><span style="height:60%"></span><span style="height:90%"></span><span style="height:100%"></span></div>
</section>
</main>
</div>| Part | Technique | Why |
|---|---|---|
| Page frame | grid-template-areas: side / top / main | Readable map, easy mobile rearrangement |
| KPI cards | repeat(auto-fit, minmax(140px, 1fr)) | Cards reflow from 4 → 2 → 1 |
| Chart panel | grid-column: 1 / -1 | Always full width inside main |
| Top bar | Flexbox space-between | One row, title left, user right |
| Bar chart | Flexbox align-items: flex-end + % heights | Bars grow from the bottom |
| Mobile | Media query redraws areas, sidebar scrolls sideways | Usable on a phone |
Professionals use Grid for the two-dimensional skeleton (page, dashboard, card grid) and Flexbox for one-dimensional pieces inside it (toolbars, button groups, card internals). That is exactly what this dashboard does.
subgrid: aligning rows across cards
<style>
.cards { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; }
.card {
display: grid;
grid-row: span 3;
grid-template-rows: subgrid; /* use the parent's row lines */
gap: 6px;
background: #fff; border: 1px solid #e5e7eb; border-radius: 12px; padding: 12px;
}
.card h3 { margin: 0; font-size: 1rem; }
.card p { margin: 0; color: #6b7280; font-size: .85rem; }
.card a { align-self: end; background: #264de4; color: #fff; text-align: center; padding: 6px; border-radius: 6px; text-decoration: none; }
</style>
<div class="cards">
<div class="card"><h3>Basic</h3><p>Notes only.</p><a href="#">Buy</a></div>
<div class="card"><h3>Pro plan with a much longer title that wraps</h3><p>Notes, tests and live doubt classes every evening.</p><a href="#">Buy</a></div>
<div class="card"><h3>Premium</h3><p>Everything + mentoring.</p><a href="#">Buy</a></div>
</div>🏅 Job skills unlocked today
Practice tasks
🏋️ Practice – do it yourself
Show solution
Quick quiz
🧠 Quick Quiz – test yourself
Interview corner
💼 Interview Corner
How would you build a responsive dashboard layout?
Grid with named areas for sidebar/topbar/main, auto-fit/minmax for KPI cards, full-width panels via grid-column: 1 / -1, Flexbox inside components, and media queries that redraw the area map and turn the sidebar into a horizontal scroller or drawer on phones.
Does visual reordering with Grid affect accessibility?
Yes – screen readers and keyboard focus follow the DOM order, not the visual order. Keep the HTML in a logical reading order and only rearrange visually where the meaning stays the same.
Summary
- grid-template-areas draws the layout as a text map.
- Redraw the map in a media query for mobile.
- Dashboards = Grid skeleton + auto-fit cards + Flexbox details.
- subgrid aligns internals across sibling cards.
Day 11: responsive design – mobile-first CSS, media queries, breakpoints and testing on real devices.
