Guide
Responsive web design explained
Responsive web design is the practice of building one HTML document that adapts its layout, typography, and interactions to the screen size and input method of the device viewing it. A phone user, a tablet reader, and a desktop visitor should all get a usable experience without maintaining separate mobile and desktop sites. The approach combines a fluid grid, flexible media, and CSS media queries — popularized by Ethan Marcotte in 2010 and still the default way modern sites ship. This guide walks through mobile-first workflow, breakpoint strategy, layout patterns with Flexbox and Grid, newer container queries, and habits that keep Core Web Vitals healthy across viewports.
What responsive design solves
Before responsive techniques, teams often built a separate m.example.com
site or served entirely different templates per device class. That doubled maintenance,
split SEO equity, and broke bookmarks when users switched devices. Responsive design
keeps one URL, one codebase, one crawlable document — the browser
reflows content based on available width.
The goal is not pixel-perfect parity on every screen. It is appropriate presentation: navigation that fits narrow viewports, readable line lengths, tappable controls on touch screens, and images that do not overflow or waste bandwidth. Google indexes mobile-first, so the narrow layout is often the baseline you must get right before adding desktop enhancements. Pair layout work with our SEO fundamentals guide so titles, canonical URLs, and structured data stay consistent across breakpoints.
Mobile-first vs desktop-first
Mobile-first means you write base CSS for small screens, then add
@media (min-width: …) rules to enhance layout as space grows.
Desktop-first does the opposite — full layout by default, then max-width
queries strip columns and shrink type. Mobile-first is the modern default for three reasons:
- Progressive enhancement — core content and navigation work even if advanced layout rules fail.
- Performance — phones download the same CSS but apply fewer expensive rules until the viewport qualifies.
- Search indexing — crawlers evaluate the mobile experience first; a broken narrow layout hurts rankings even if desktop looks fine.
In practice, mobile-first CSS often looks like a single column, full-width images with
max-width: 100%, and a hamburger or collapsible nav. At min-width:
48rem (768px) you might switch to a two-column article + sidebar; at
64rem (1024px) you expose horizontal nav links and widen gutters.
The viewport meta tag
Without a viewport declaration, mobile browsers assume a ~980px-wide "layout viewport" and shrink the page to fit — tiny text, horizontal scrolling, unusable tap targets. Every responsive page needs:
<meta name="viewport" content="width=device-width, initial-scale=1.0">
width=device-width sets the layout viewport to the device screen width.
initial-scale=1.0 avoids accidental zoom on load. Avoid disabling user
zoom (user-scalable=no) — it harms accessibility and can fail WCAG
requirements covered in our
accessibility guide.
Safe areas and notches
On phones with display cutouts, use env(safe-area-inset-*) padding on
fixed headers and footers so content does not sit under the notch or home indicator.
Test in device emulation with "show device frame" enabled in browser DevTools.
Breakpoints: content-driven, not device catalogs
A breakpoint is the viewport width where your layout changes — often where a multi-column grid would become unreadably narrow. Resist copying "iPhone breakpoint 375px, iPad 768px" lists from blog posts. Those numbers drift every hardware generation. Instead:
- Resize the browser until the design breaks — that width is your breakpoint.
- Name breakpoints by intent —
--bp-nav-expandnot--iphone-plus. - Prefer min-width queries in mobile-first stacks; keep the count low (two to four breakpoints cover most content sites).
Common starting points (adjust to your content): 36rem (576px) for
slightly roomier type; 48rem for two-column layouts; 64rem
for full navigation and max content width; 80rem for ultra-wide
hero treatments. Use rem breakpoints so they respect user font-size settings.
Container queries: responsive components
Media queries respond to the viewport. Container queries respond to a parent element's width — a card grid can switch from one column to three based on the sidebar width, not the whole window. Enable with:
.card-grid { container-type: inline-size; }
@container (min-width: 28rem) {
.card-grid { grid-template-columns: repeat(2, 1fr); }
}
Container queries pair naturally with CSS Grid auto-fit patterns in design systems where the same component appears in main content, sidebars, and modals.
Fluid typography and spacing
Jumping font sizes at breakpoints can feel jarring. Fluid typography
interpolates between minimum and maximum sizes using clamp():
h1 {
font-size: clamp(1.75rem, 1.2rem + 2vw, 2.75rem);
line-height: 1.15;
}
The middle term scales with viewport width (vw); the min and max cap
readability on phones and ultra-wide monitors. Apply the same idea to section padding
and grid gaps so whitespace breathes on large screens without wasting mobile pixels.
For body copy, aim for 45–75 characters per line. Use
max-width: 65ch on article columns. Line height around 1.5–1.7 improves
scanability. These choices affect Largest Contentful Paint less than hero images do —
see our
image optimization guide
for LCP-focused asset work.
Layout patterns that scale
Stack to row with Flexbox
Navigation bars, toolbars, and card footers often use display: flex; flex-wrap:
wrap; gap: 1rem; so items wrap on narrow screens and sit in a row when space
allows. justify-content: space-between pushes logo and menu apart on wide
layouts; on narrow screens, stack with flex-direction: column inside a
media or container query.
Responsive grids without breakpoint soup
CSS Grid's repeat(auto-fit, minmax(min(100%, 18rem), 1fr)) creates
responsive card grids with zero media queries — cards reflow automatically as the
container narrows. Combine with consistent gap and equal-height cards via
align-items: stretch.
Responsive images and media
Never ship a 2400px-wide JPEG inside a 360px column. Use srcset and
sizes so the browser picks an appropriate file, set explicit width
and height attributes to reserve space (preventing layout shift), and lazy-load
below-the-fold images. Modern formats (WebP, AVIF) cut bytes on cellular connections —
details in the dedicated image guide linked above.
Tables and wide data
Data tables overflow small screens. Options: horizontal scroll inside
overflow-x: auto with a visual hint; collapse rows into labeled blocks
with display: block on tr/td at narrow widths; or hide
low-priority columns via display: none with a "show all columns" toggle.
Never shrink table text below 14px to force fit — readability wins.
Touch, pointer, and input modes
Responsive design is not only about width. Touch users need 44×44 CSS pixel minimum tap targets (Apple HIG and WCAG guidance). Space adjacent links; use padding instead of tiny icons. Hover-only menus fail on phones — expose the same destinations via tap or a visible menu button.
The @media (hover: hover) and (pointer: fine) query lets you add hover
underlines and tooltips only for mouse users, while touch users get always-visible
labels. prefers-reduced-motion should disable parallax and large
transitions for vestibular accessibility.
Fixed position headers and cookie banners steal vertical space on short viewports.
Consider position: sticky for section headings instead of a permanently
fixed chrome bar on mobile, or collapse the header on scroll to preserve reading area.
Performance and Core Web Vitals across viewports
Mobile networks and CPUs are the bottleneck. A layout that scores 95 on desktop Lighthouse can fail on a mid-range Android phone. Responsive habits that protect vitals:
- LCP — optimize the hero image or font above the fold; avoid loading desktop-only assets on mobile.
- CLS — reserve space for images, ads, and web fonts; do not inject content above existing text after load.
- INP — keep main-thread work small; debounce resize handlers; the event loop guide explains why long tasks hurt tap responsiveness.
Test on real devices or Chrome DevTools device emulation with CPU throttling (4×). Responsive CSS is cheap; unoptimized images and JavaScript bundles are not.
Testing checklist
- Resize from 320px to 1920px — no horizontal scroll unless intentional (tables).
- Rotate portrait/landscape on phone emulation — nav and forms still usable.
- Zoom text to 200% — content reflows without loss (WCAG reflow criterion).
- Tab through interactive elements — focus rings visible at every width.
- Run Lighthouse mobile audit — fix LCP/CLS/INP before shipping.
- Spot-check on one real iOS and one real Android device if possible.
Key takeaways
- One URL, adaptive layout — responsive design beats separate mobile sites for SEO and maintenance.
- Mobile-first CSS — base styles for narrow screens,
min-widthqueries for enhancement. - Content-driven breakpoints — add queries where the design breaks, not from device lookup tables.
- Fluid type and Grid auto-fit reduce breakpoint sprawl while keeping typography readable.
- Touch targets and input modes matter as much as column count.
- Test on throttled mobile — responsive layout means nothing if images and JS tank Core Web Vitals.
Related reading
- CSS Flexbox and Grid layout explained — axes, fr units, and responsive card grids
- Core Web Vitals explained — LCP, INP, and CLS thresholds
- Web image optimization explained — srcset, formats, and lazy loading
- Web accessibility (a11y) explained — keyboard, contrast, and reflow