Day 10 — Responsive design - one page, every screen
More than half your visitors are on a phone. A page that only works on your laptop is a page that mostly does not work.
It starts with one line of HTML
Without it a phone pretends to be a 980px desktop and shrinks the whole page to fit, so your text ends up microscopic. No amount of CSS fixes that. It goes in the head of every page you ever write.
Media queries
/* only applies at 700px and wider */
}
The preview panes below are narrow, which makes them a decent stand-in for a phone. Drag the corner of your browser window to see the switch happen on this page too.
<style>
body { font-family:system-ui, sans-serif; }
.box { background:#E8EEF8; padding:20px; }
.box p { margin:0; font-weight:700; }
@media (min-width: 600px) {
.box { background:#FDF3DA; }
.box p::after { content: " - wide layout"; }
}
</style>
<div class="box"><p>Narrow layout</p></div>
The preview is under 600px wide, so you see the blue version. Widen your browser and this whole page reflows too - the tutorial is built the same way.
Mobile-first
Write the phone styles as your normal CSS, then add what changes on bigger screens. Doing it the other way round means every rule needs an override, and phones - the slower devices - end up doing the most work.
<style>
*, *::before, *::after { box-sizing:border-box; }
body { font-family:system-ui, sans-serif; margin:0; padding:14px; }
/* phone first: everything stacks */
.grid { display:grid; gap:12px; }
.grid div { background:#E8EEF8; padding:16px; border-radius:8px; }
/* tablet */
@media (min-width: 560px) {
.grid { grid-template-columns: 1fr 1fr; }
}
/* desktop */
@media (min-width: 900px) {
.grid { grid-template-columns: 1fr 1fr 1fr; }
}
</style>
<div class="grid">
<div>Excel</div><div>Power BI</div>
<div>SQL</div><div>Python</div>
</div>
Images that behave
Two lines that stop every image from bursting out of its container. max-width: 100% means "never wider than the space available"; height: auto keeps the proportions right.
<style>
img { max-width:100%; height:auto; display:block; }
.frame { max-width:220px; border:2px solid #1D3B73; padding:6px; }
</style>
<div class="frame">
<img src="https://dai-academy.com/assets/logo.png"
alt="DAI Academy logo" width="800" height="250">
</div>
The image file is far wider than 220px, but it shrinks to fit instead of breaking out. The width and height attributes stay on the tag so the browser can reserve the right space while it loads.
Units that flex
| Unit | Means | Good for |
|---|---|---|
px | Fixed pixels | Borders, small fixed gaps |
% | Of the parent | Widths |
rem | Multiple of the root font size | Type and spacing - scales if the user enlarges text |
em | Multiple of this element’s font size | Padding that should track the text |
vw / vh | Percent of the window | Full-height heroes |
ch | Width of a "0" | max-width: 70ch for a readable line length |
<style>
html { font-size:16px; }
.a { font-size:1.5rem; }
.b { max-width:34ch; background:#E8EEF8; padding:.75rem; }
.c { font-size: clamp(16px, 4vw, 26px); }
</style>
<p class="a">1.5rem is 24px here</p>
<p class="b">This paragraph is capped at 34 characters wide, which forces
a short line length whatever the screen size.</p>
<p class="c">clamp: at least 16px, ideally 4vw, never more than 26px</p>
clamp(min, ideal, max) in one line replaces two media queries. Resize your browser and watch that last paragraph grow, then stop growing at 26px.A responsive table
Day 4 showed the wrapper. Here it is with the CSS that makes it work.
<style>
.scroller { overflow-x:auto; -webkit-overflow-scrolling:touch; }
table { border-collapse:collapse; min-width:520px; font-size:14px; }
th, td { border:1px solid #D3DDEC; padding:8px 12px; text-align:left; }
th { background:#E8EEF8; }
</style>
<div class="scroller">
<table>
<thead><tr>
<th>Course</th><th>Duration</th><th>Fee</th>
<th>Batch</th><th>Mode</th>
</tr></thead>
<tbody><tr>
<td>Advanced Excel</td><td>6 weeks</td><td>12,000</td>
<td>Weekday</td><td>Classroom</td>
</tr></tbody>
</table>
</div>
min-width on the table stops the columns from crushing; overflow-x: auto on the wrapper lets the table scroll instead of the page. The rule is: the page must never scroll sideways. Something inside it may.
Touch targets
<style>
.tiny a { font-size:12px; }
.good a {
display:inline-block; padding:12px 16px; min-height:44px;
line-height:20px; background:#E8EEF8; border-radius:8px;
text-decoration:none; color:#0A1A3D;
}
</style>
<p class="tiny"><a href="https://example.com">Hard to tap</a></p>
<p class="good"><a href="https://example.com">Easy to tap</a></p>
Try these yourself
- Build a three-column card grid that becomes two columns, then one, as the screen narrows.
- Set an image to max-width 100% and prove it cannot overflow its container.
- Use clamp to make a heading scale between 20px and 40px.
- Wrap a six-column table so it scrolls sideways without moving the page.
- Explain why mobile-first CSS produces less code than desktop-first.
