← Back to the Responsive Design Playground
Lesson

Responsive Design, Visually

One website should look right on a phone, a tablet, and a wide monitor. This visual lesson covers the viewport tag, fluid units, media queries, mobile-first thinking, responsive images and type — with a live device simulator whose own media queries fire as you switch screen sizes.

Step 1

What responsive design is — and why

Responsive web design means one codebase that adapts its layout to any screen, instead of a separate “mobile site.” The same HTML reflows: columns stack on phones, sit side-by-side on desktops.

It matters because most web traffic is now on phones, screen sizes vary enormously, and search engines rank mobile-friendly pages higher. Three tools do nearly all the work: fluid units, media queries, and flexible layout (Flexbox/Grid).

The mindset shift: stop designing “a page” at one fixed width. Design content that flows, then add a few rules that rearrange it when there's more or less room.
Step 2

The viewport meta tag (do this first)

Without this one line in your <head>, phones pretend to be ~980px wide and shrink your whole page to fit — your media queries never fire. It's the non-negotiable first step of any responsive page:

<meta name="viewport" content="width=device-width, initial-scale=1.0">
Without itWith it
Phone renders at ~980px, then zooms out — tiny, unreadable text.Page uses the real device width; text is legible, media queries work.
If responsive CSS “isn't working” on a phone, check this first. A missing viewport tag is the single most common reason media queries appear to do nothing.
Step 3

Fluid units beat fixed pixels

Fixed widths like width: 960px overflow small screens. Relative units flex with the space available:

UnitRelative toUse for
%The parent's sizeFluid widths inside a container.
remRoot font sizeFont sizes & spacing that scale accessibly.
vw / vh1% of viewport width / heightFull-screen heroes, big fluid type.
max-widthA ceiling, not a fixed sizemax-width: 100% keeps things from overflowing.
min() / max() / clamp()Computed boundsFluid-but-capped sizes (Step 9).
The single most useful rule: max-width: 100% on images and containers. It says “never be wider than the space you have” — the quickest fix for horizontal scrollbars on phones.
Step 4

Media queries

A media query applies a block of CSS only when a condition is true — usually a viewport width. min-width means “this wide or wider” (the mobile-first direction).

/* base styles: phone — one column */
.cards { display: grid; grid-template-columns: 1fr; gap: 16px; }

@media (min-width: 600px) {        tablet+ */
  .cards { grid-template-columns: 1fr 1fr; }
}
@media (min-width: 900px) {        desktop */
  .cards { grid-template-columns: 1fr 1fr 1fr; }
}
A breakpoint is just the width where you change the layout. Pick them where your content starts to look cramped — not by chasing specific device models. The simulator below runs exactly this CSS.
Step 5

Live: watch a layout adapt

This is a real mini web page inside a frame. Switch the device — its own media queries fire based on the frame's width, so the navigation, columns, and hero genuinely rearrange (not a fake mockup):

375px
At phone width the nav collapses and cards stack in one column; at tablet they become two columns; on desktop the nav spreads out and cards go three-across — all from min-width media queries inside the frame.
Step 6

Mobile-first

Write your base styles for the smallest screen, then use min-width queries to add complexity as the screen grows. This is easier than the reverse and produces less code.

Why mobile-first wins: the simplest layout is the default, so a phone (the most constrained device) never has to “undo” desktop styles. You only ever add, never override away.
Step 7

Fluid layouts (sometimes no query needed)

Modern Flexbox and Grid can be responsive with zero media queries. The auto-fit grid fits as many columns as will comfortably fit and wraps the rest:

.gallery {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 20px;
}

Likewise, a flex row with flex-wrap: wrap drops items to new lines as space runs out. Reach for media queries when you need a deliberate change (hide a sidebar, swap a layout); reach for fluid layout for everything that should just flow.

This very page uses fluid layout — the “Where next” cards below and the lesson tables reflow on resize with no breakpoints of their own.
Step 8

Responsive images

An image with a fixed width overflows phones. The fix is one rule; the upgrade is serving smaller files to smaller screens.

The baseline (always do this)

img { max-width: 100%; height: auto; }   never overflow; keep aspect ratio
A river winding through a canyon
max-width: 100% — resize the window; the image shrinks but never overflows

The upgrade: send the right size

<img src="photo-800.jpg"
     srcset="photo-400.jpg 400w, photo-800.jpg 800w, photo-1200.jpg 1200w"
     sizes="(max-width: 600px) 100vw, 50vw"
     alt="A mountain at sunrise">
srcset lists the available widths; sizes tells the browser how much space the image will occupy, so it downloads the smallest file that still looks sharp — faster pages on phones, no wasted data.

Responsive video & embeds

Videos and embedded iframes (YouTube, maps) don't shrink on their own — they keep a fixed size and overflow. Wrap them in a box with aspect-ratio: 16 / 9 and let the media fill it. Now it scales with the column and keeps its shape:

aspect-ratio: 16 / 9 — the video resizes with the page and never distorts
.video-wrap { width: 100%; aspect-ratio: 16 / 9; }
.video-wrap video,
.video-wrap iframe { width: 100%; height: 100%; }
Same wrapper works for a YouTube <iframe> — drop the embed inside .video-wrap and it becomes fully responsive. Before aspect-ratio existed, people faked this with a padding-top: 56.25% trick — you'll still see it in older code.
Step 9

Fluid typography with clamp()

clamp(min, preferred, max) sets a size that scales with the viewport but never goes below the min or above the max — smooth, breakpoint-free responsive text. Resize this window and watch the heading grow and shrink:

This heading is fluid
font-size: clamp(1.1rem, 5vw, 2.6rem)
h1 { font-size: clamp(1.5rem, 5vw, 3rem); }
Read it as: “ideally 5% of the viewport width, but never smaller than 1.5rem or larger than 3rem.” One line replaces three font-size media queries.
Step 10

Responsive checklist

Where next

Keep going