Topic 9.1
Responsive Design Principles
In one line
Responsive design means one page whose layout adapts to any screen: start with the small-screen layout (mobile first), size things fluidly instead of in fixed pixels, and add the viewport meta tag so phones show the page at its real width.
Think of it like this
Water in a container. Pour water into a tall glass, a wide bowl or a bottle and it takes the shape of each one, without you making three kinds of water. A responsive page is like water: the same content flows into a narrow phone, a medium tablet or a wide laptop and fills each one sensibly. A fixed page is like an ice block: it fits one container and sticks out of every smaller one.
Words you'll meet
New words in this topic, in plain English. Come back here whenever one feels fuzzy.
- Viewport
- The visible area of the browser window where the page is drawn.
- Responsive design
- Building one page whose layout adapts to any screen size, input and user setting.
- Mobile first
- Writing the small-screen CSS first, then adding rules for bigger screens with
min-widthmedia queries. - Fluid layout
- A layout whose sizes are relative (%,
fr,vw,max-width), so it stretches and shrinks with the space. - Fixed layout
- A layout built with fixed pixel widths, which breaks or scrolls sideways on smaller screens.
- Layout viewport
- The width the browser uses to lay out the page. Without the viewport meta tag, phones pretend it is about 980px.
- Viewport meta tag
<meta name="viewport" content="width=device-width, initial-scale=1">: tells phones to use their real width.- Breakpoint
- A width where the layout changes, set with a media query.
- Intrinsic layout
- A layout that adapts by itself from its content and space (wrapping flex, Grid
auto-fit), with no media query.
Step by step
01Start with the viewport meta tag
Put this in the <head> of every page. Without it, a phone lays the page out at about 980px and shrinks it, so text is tiny and your media queries never fire. width=device-width makes the layout viewport the device's width in CSS pixels; initial-scale=1 starts at 100% zoom.
Don't add maximum-scale=1 or user-scalable=no: they stop people from pinch-zooming, which fails accessibility guidelines (WCAG 1.4.4, Resize Text).
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>My page</title>
</head>02Write the small-screen CSS first
With no media query at all, the page should already work on a phone: one column, full-width blocks, readable text, images that shrink. Most of your CSS lives here, and it applies to every screen.
/* every screen, starting with the smallest */
.page {
padding-inline: 1rem;
}
.cards {
display: grid;
gap: 1rem; /* one column by default */
}
img {
max-width: 100%;
height: auto;
}03Make the container fluid, with a limit
Let the content column fill the screen, but stop it growing past a comfortable width and centre it. max-width is the limit and margin-inline: auto centres it (Topic 9.7 explains margin-inline).
.page {
max-width: 60rem;
margin-inline: auto; /* centre once it stops growing */
padding-inline: 1rem; /* never touch the screen edge */
}04Add layout for wider screens
When there is room, add columns with a min-width media query. Each query adds to the mobile CSS instead of undoing it.
@media (min-width: 40rem) {
.cards { grid-template-columns: 1fr 1fr; }
}
@media (min-width: 64rem) {
.cards { grid-template-columns: repeat(3, 1fr); }
}05Or let the layout decide by itself
Grid's auto-fit with minmax() (Phase 8, Topic 8.2) fits as many columns as there is room for, with no breakpoints at all. min(100%, 14rem) stops a card from overflowing a screen narrower than 14rem.
.cards {
display: grid;
gap: 1rem;
grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr));
}06How a phone decides the width
This is what happens on a phone with and without the meta tag.
Try it yourself
- 1
Find the overflow
In the first example, predict what happens if you change
.fixedtowidth: 100%; max-width: 500px;. Run it: the scrollbar disappears. A fixed width is only a problem when it is wider than the screen. - 2
Move the breakpoints
In the mobile-first example, open the full-screen editor and slowly widen the window. Note the width where two columns start to look cramped, and move the
50rembreakpoint to match. You just chose a breakpoint from your content, not from a device list. - 3
Change the minimum card size
In the intrinsic grid, change
9remto14rem. Predict: will you see more or fewer columns at the same width? (Fewer, because each column needs more room.)
Code & diagrams
The preview is narrow, so the red box overflows and you get a sideways scrollbar. The green box fits. Widen the preview (or your window) past 500px and both look the same; that's why fixed widths seem fine on a desktop and break on a phone.
Preview
Console
Nothing logged yet.In the narrow preview you see one column. Open the full-screen editor or widen your window: at 30rem (480px) it becomes two columns, at 50rem (800px) three.
Preview
Console
Nothing logged yet.Resize the window: the number of columns changes by itself. This is often better than media queries for lists of cards, because it reacts to the space the grid really has.
Preview
Console
Nothing logged yet.The tag only has an effect on mobile browsers; desktop browsers ignore it. The last line is a small audit you could run on your own pages: blocking zoom is an accessibility failure.
Preview
Console
Nothing logged yet.Expected console output
viewport: width=device-width, initial-scale=1
[ 'width=device-width', 'initial-scale=1' ]
blocks zoom? falseBreak it on purpose
Errors are the best teachers. Make each change, read the error, guess what went wrong, then reveal the answer.
Break #1
Forget the viewport meta tag
Delete <meta name="viewport" ...> from a real page and open it on a phone (or DevTools' device toolbar).
Break #2
A long word or a wide element
Put a very long URL in a paragraph, or give an element width: 500px, in a fluid page.
Myth vs fact
Myth
Responsive means making a separate mobile site.
Fact
Responsive means one HTML page and one stylesheet that adapt. Separate "m-dot" sites (m.example.com) are an older, different approach that duplicates content.
Myth
Breakpoints should match popular devices, like 375px and 768px.
Fact
Breakpoints should be where your content breaks. Device sizes change every year, and the same width can be a phone in landscape, a small tablet or a zoomed laptop.
Myth
Mobile first means designing only for phones.
Fact
It means the order you write CSS in: small screen as the base, larger screens added with min-width queries. Desktop gets a full layout too.
Myth
user-scalable=no makes a page feel more like an app.
Fact
It stops people with low vision from zooming and fails WCAG. Modern iOS Safari ignores it anyway. Never block zoom.
Pro corner
Extra depth for experienced readers. New to this? Skip it for now and come back later.
- ▸
Media query widths are measured in CSS pixels, not device pixels. A phone with a 1170-pixel-wide screen and a device pixel ratio of 3 has a 390 CSS-pixel viewport (Phase 3, Topic 3.1). Zoom also changes CSS pixels: at 200% zoom, a 1280px window has a 640px viewport and gets your mobile layout.
- ▸
Since about 2016, mobile browsers skip the 300ms tap delay (they used to wait to see if you'd double-tap to zoom) on pages with
width=device-width. That's another reason the tag matters for feel, not only layout. - ▸
Other viewport meta keys exist:
viewport-fit=coverlets the page draw under a phone's notch (you then pad withenv(safe-area-inset-left)etc.), andinteractive-widget=resizes-content(Chromium) controls whether the on-screen keyboard resizes the layout viewport. Use them only when you need them. - ▸
Intrinsic techniques (
flex-wrap,auto-fit,min()/clamp(), container queries) usually beat breakpoints for components, because they respond to the space the component has, not the window. Keep media queries for page-level decisions like showing a sidebar.
Remember this
- 1
The viewport is the rectangle of the browser window where the page is drawn. Responsive design (a name coined by Ethan Marcotte in 2010) is a set of habits that make one page work at every viewport size: fluid layouts (sizes that stretch and shrink), flexible media (images that never overflow), and media queries (rules that only apply at certain sizes, Topic 9.2). Today you add a fourth: intrinsic layouts that adapt by themselves, with Flexbox wrapping, Grid's
auto-fitand container queries. - 2
Mobile first means you write the CSS for the smallest screen first, with no media query, and then add rules for wider screens with
min-widthqueries. Small screens get the simplest layout (usually one column), and each larger size adds layout on top. The opposite, desktop first, writes the big layout and then undoes it withmax-widthqueries; it tends to produce more CSS and more overrides. Mobile first also forces you to decide what content really matters, because a phone has no room for clutter. - 3
A fluid layout uses sizes relative to the space available: percentages,
frunits,flex,vw, and limits likemax-width. The classic pattern is a centered column:max-width: 60rem; margin-inline: auto; padding-inline: 1rem;. On a phone it fills the screen minus a small gutter; on a laptop it stops growing at 60rem and centres itself. Comparewidth: 960px, which forces a horizontal scrollbar on any screen narrower than 960px. - 4
Phones have a trap. Early mobile browsers assumed every web page was designed for desktop, so they draw the page on a virtual canvas about 980px wide (the layout viewport) and shrink it to fit the screen. Your page looks like a tiny desktop page, and your media queries see 980px, not 390px. The viewport meta tag turns that off:
<meta name="viewport" content="width=device-width, initial-scale=1">says "make the layout viewport as wide as the device, in CSS pixels, and don't zoom". Every responsive page needs it in the<head>. - 5
Breakpoints are the widths where your layout changes, for example from one column to two. Choose them where your content starts to look wrong (lines too long, cards too squashed), not from a list of popular phone models: devices change every year, content doesn't. Two or three breakpoints are usually enough, and many components need none if they use intrinsic layouts.
- 6
Responsive is more than width. The same principles cover zoom (a user at 200% zoom on a 1280px laptop gets a 640px CSS viewport and sees your mobile layout, which is correct), user preferences like dark mode (Topic 9.3), input type (touch or mouse), and language direction (Topic 9.7). Test by resizing the browser, using DevTools' device toolbar, zooming, and on at least one real phone.
Explain it without notes
What is responsive design, and what are its main ingredients?
What does the viewport meta tag do, and what happens without it?
What does "mobile first" mean in CSS, and why is it usually preferred?
How should you choose breakpoints?
Practice
Write the HTML <head> lines and CSS for a page wrapper that fills a phone with a 16px gutter and stops at 720px wide, centred, on larger screens.
Rewrite this desktop-first CSS as mobile first: .nav { display: flex; } @media (max-width: 599px) { .nav { display: block; } }.
Make a list of product cards that shows as many columns as fit, each at least 200px wide, without any media query and without overflowing a 180px-wide screen.
Trade-offs
- ↔
Mobile first gives simpler base CSS and fewer overrides, but if most of your users are on desktop and the desktop layout is far more complex, you'll write a lot inside
min-widthqueries; that's still usually clearer than undoing a desktop layout. - ↔
Intrinsic layouts need fewer breakpoints and react to real space, but give you less exact control over where the layout changes than explicit media queries.
Done when you can
I can add the correct viewport meta tag and explain what it fixes.
I can explain mobile first and write CSS in that order.
I can build a fluid, centred page wrapper with
max-width.I can choose breakpoints from my content, in
remorem.I can build a responsive card grid with no media queries.
I know that zoom changes the CSS viewport width.