Day 11: Responsive Design & Media Queries
✅ Today you will learn
- Why 70%+ of Indian visitors decide your site on a phone
- The viewport meta tag and fluid layouts
- Mobile-first CSS with min-width media queries
- Breakpoints that follow content, not devices
- Responsive navbar, images, typography; container queries; testing
🏢 In the real world
A real e-mail from a school principal: “The admission page looks perfect on my office computer, but parents say on their phones the text is tiny, the table goes off the screen and the menu covers everything.” Today you learn the exact process professionals use to make one codebase look right on a ₹7,000 Android phone and a 27-inch monitor.
Step 0: the viewport meta tag
<meta name="viewport" content="width=device-width, initial-scale=1">
Without this line, phones pretend to be a 980px-wide desktop and shrink the whole page – tiny unreadable text. It is the cause of the principal’s first complaint.
Step 1: fluid by default
- Use max-width instead of width:
.container { max-width: 1100px; margin: 0 auto; padding: 0 16px; } - Images never overflow:
img { max-width: 100%; height: auto; } - Layouts with fr, %, flex-wrap and auto-fit grids adapt on their own (Days 7–10).
- Wide tables scroll inside a wrapper with
overflow-x: auto(Day 6). - Fonts in rem; headings can scale with clamp() (Day 12).
Step 2: media queries
/* Styles for ALL screens (phones first) */
.cards { display: grid; gap: 16px; grid-template-columns: 1fr; }
/* From 600px wide and up (large phones, tablets) */
@media (min-width: 600px) {
.cards { grid-template-columns: 1fr 1fr; }
}
/* From 1024px and up (laptops) */
@media (min-width: 1024px) {
.cards { grid-template-columns: repeat(4, 1fr); }
}Desktop-first (max-width)
- Write desktop CSS, then undo it for phones
- Phones download and override big-screen rules
- More code, more bugs
Mobile-first (min-width) ⭐
- Simple one-column CSS first
- Add columns as space grows
- Matches how most Indian users browse
| Breakpoint (min-width) | Typical screens | Common change |
|---|---|---|
| — (base) | Phones 360–430px | 1 column, ☰ menu, stacked forms |
| 600px | Large phones landscape, small tablets | 2 columns |
| 768px | Tablets | Horizontal nav, sidebar appears |
| 1024px | Laptops | 3–4 columns, wider hero |
| 1280px | Desktops | Max container width, bigger spacing |
Do not chase device sizes. Widen the browser slowly; where the layout starts to look stretched or cramped, that is your breakpoint. Use em/rem in queries (e.g. 48em) so they also respect zoom.
Real component: responsive navbar
<style>
* { box-sizing: border-box; }
body { margin: 0; }
.site-nav { background: #264de4; color: #fff; }
.bar { display: flex; justify-content: space-between; align-items: center; padding: 12px 16px; }
.logo { font-weight: 800; }
.toggle { background: none; border: 2px solid #fff; color: #fff; border-radius: 6px; padding: 4px 10px; font-size: 1.1rem; }
.links { display: none; list-style: none; margin: 0; padding: 0 16px 12px; }
.site-nav.open .links { display: block; }
.links a { display: block; color: #fff; padding: 8px 0; text-decoration: none; border-top: 1px solid rgb(255 255 255 / 20%); }
/* ---- tablet and up: horizontal menu, no toggle ---- */
@media (min-width: 640px) {
.site-nav { display: flex; justify-content: space-between; align-items: center; padding-right: 16px; }
.toggle { display: none; }
.links { display: flex; gap: 20px; padding: 0; }
.links a { border: 0; }
}
</style>
<nav class="site-nav" id="nav">
<div class="bar">
<span class="logo">🍬 Sharma Sweets</span>
<button class="toggle" aria-expanded="false" aria-controls="menu"
onclick="nav.classList.toggle('open'); this.setAttribute('aria-expanded', nav.classList.contains('open'))">☰</button>
</div>
<ul class="links" id="menu">
<li><a href="#">Home</a></li><li><a href="#">Menu</a></li><li><a href="#">About</a></li><li><a href="#">Order</a></li>
</ul>
</nav>
<p style="padding:0 16px">Narrow the window below 640px to see the ☰ button.</p>The button only toggles a class (open) and updates aria-expanded for screen readers – all the visual work is CSS. You will write this properly in the JavaScript course.
Other useful media features
| Query | Use |
|---|---|
| (orientation: landscape) | Phone turned sideways – shorter hero |
| (hover: hover) | Only add hover effects where a mouse exists |
| (prefers-color-scheme: dark) | Dark mode (Day 12) |
| (prefers-reduced-motion: reduce) | Turn off animations for motion-sensitive users (Day 14) |
| Hide nav/buttons, black text when printing invoices |
@media print {
nav, footer, .btn, .wa { display: none; }
body { color: #000; background: #fff; font-size: 12pt; }
a[href]::after { content: " (" attr(href) ")"; } /* show link URLs on paper */
}Container queries: components that adapt to their box
<style>
.wrap { container-type: inline-size; border: 1px dashed #94a3b8; padding: 8px; margin-bottom: 10px; border-radius: 8px; }
.item { display: grid; gap: 10px; }
.item img { width: 100%; border-radius: 8px; aspect-ratio: 4/3; object-fit: cover; }
@container (min-width: 380px) {
.item { grid-template-columns: 140px 1fr; align-items: center; }
}
</style>
<div class="wrap" style="max-width:300px"><div class="item"><img src="images/ladoo-400.webp" alt="Ladoo"><div><b>Besan Ladoo</b><p>₹500/kg · narrow box → stacked</p></div></div></div>
<div class="wrap"><div class="item"><img src="images/ladoo-400.webp" alt="Ladoo"><div><b>Besan Ladoo</b><p>₹500/kg · wide box → side by side</p></div></div></div>Testing like a professional
- 1DevTools → Ctrl+Shift+M → choose “Responsive” and drag from 320px to 1440px
- 2Check common phones: Galaxy A-series (360px), iPhone (390px), tablets (768px)
- 3Look for: horizontal scrollbar, text < 16px, buttons < 44px tall, overlapping elements
- 4Find the culprit of sideways scroll: in Console run [...document.querySelectorAll("*")].filter(e => e.scrollWidth > innerWidth)
- 5Finally test on a real low-end Android phone over 4G
🏅 Job skills unlocked today
Practice tasks
🏋️ Practice – do it yourself
Show solution
Quick quiz
🧠 Quick Quiz – test yourself
Interview corner
💼 Interview Corner
What is mobile-first design and why use it?
Writing the base CSS for small screens and layering enhancements with min-width media queries. It keeps base CSS simple, avoids overriding desktop rules on phones, prioritises content and performance for the majority of mobile users.
How do you find what causes horizontal scrolling on mobile?
Use DevTools device mode, then find elements wider than the viewport (outline everything temporarily or filter elements whose scrollWidth exceeds innerWidth). Usual culprits: fixed widths, long words/URLs, images without max-width, 100vw with scrollbars, negative margins.
Summary
- Viewport meta + fluid units first.
- Mobile-first: base styles, then min-width queries.
- Breakpoints where content breaks (≈600 / 768 / 1024).
- Container queries for components; test in DevTools and on a real phone.
Day 12: CSS variables, calc(), clamp() and a dark-mode theme switch.
