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:

  1. Progressive enhancement — core content and navigation work even if advanced layout rules fail.
  2. Performance — phones download the same CSS but apply fewer expensive rules until the viewport qualifies.
  3. 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-expand not --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-width queries 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