What is responsive design?
Responsive design is the practice of building one layout that adapts to every screen. Instead of a separate mobile site, you write a fluid base layout, add breakpoints where the structure needs to change, and let media shrink or grow to fit.
It became the default because it is simply better engineering: one codebase, one set of content, one URL to rank and share. Modern CSS — Flexbox, Grid, fluid units and container queries — makes it easier than it has ever been.
The viewport tag
Everything starts with the viewport meta tag.
<!-- index.html -->
<meta name="viewport" content="width=device-width, initial-scale=1" />
Without it, mobile browsers assume a desktop-width viewport and zoom out, which makes text tiny and breaks your breakpoints. With it, the CSS pixel width matches the device, so media queries behave predictably.
Mobile-first
Write your base styles for small screens, then enhance for larger ones with min-width.
/* mobile-first.css */
.grid {
display: grid;
grid-template-columns: 1fr;
gap: 1rem;
}
@media (min-width: 768px) {
.grid {
grid-template-columns: repeat(2, 1fr);
}
}
@media (min-width: 1024px) {
.grid {
grid-template-columns: repeat(3, 1fr);
}
}
Mobile-first tends to produce simpler CSS: you add rules as the screen grows rather than overriding them. It also keeps the small-screen experience as the baseline, which matters because most traffic is mobile.
Breakpoints
Breakpoints are where the layout needs to change, not where a particular device sits.
- Resize the window slowly and watch for problems: lines too long, columns too narrow, elements colliding.
- Add a
min-widthquery at the point where it breaks. - Reuse a small set of breakpoints across the project for consistency.
- Let Grid’s
auto-fitandminmax()handle many cases without any query.
/* auto.css */
.cards {
display: grid;
gap: 1.5rem;
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
}
That single rule replaces several breakpoints by creating as many columns as fit.
Fluid units
Fixed pixel widths cannot adapt. Prefer units that scale:
%relative to the parent.remrelative to the root font size, ideal for spacing and type.vw/vhrelative to the viewport.frfractions of available space in Grid.chroughly the width of a character, useful for line length.
/* fluid.css */
.page {
width: min(100% - 2rem, 64rem);
margin-inline: auto;
}
.prose {
max-width: 65ch;
}
h1 {
font-size: clamp(1.75rem, 5vw, 3rem);
}
clamp(min, preferred, max) is especially useful: it scales with the viewport but never goes below the minimum or above the maximum, replacing a pile of media queries for fluid typography and spacing.
Flexible media
Images and video must never overflow their container.
/* media.css */
img,
video {
max-width: 100%;
height: auto;
}
For real performance, also serve appropriately sized images with srcset and sizes, and set width and height (or aspect-ratio) so the layout does not shift as they load. The Web Performance guide covers responsive images in depth.
Container queries
Viewport media queries force components to know about the page. Container queries let a component respond to its own container instead.
/* container.css */
.card-list {
container-type: inline-size;
}
.card {
display: grid;
gap: 1rem;
}
@container (min-width: 30rem) {
.card {
grid-template-columns: 8rem 1fr;
}
}
Now the same card adapts whether it sits in a narrow sidebar or a wide main column, which makes components genuinely reusable. Support is now broad enough to use in production.
Touch, targets and typography
- Make tap targets at least 44×44 CSS pixels.
- Keep body text around 16px minimum so mobile browsers do not zoom on focus.
- Limit line length to roughly 45–75 characters for readability.
- Avoid hover-only interactions; provide touch-friendly alternatives.
- Test with the keyboard and with a real device, not just a resized window.
Testing
- Use the browser’s responsive mode to check many widths quickly.
- Test on real phones; emulation misses real performance and touch behaviour.
- Check landscape and portrait.
- Zoom to 200% and confirm nothing breaks.
- Test long content, not just the happy path with short strings.
Best practices
- Always include the viewport meta tag.
- Design mobile-first and enhance with
min-widthqueries. - Let Grid’s
auto-fitandminmax()replace many breakpoints. - Use fluid units and
clamp()for type and spacing. - Make images and media shrink with
max-width: 100%. - Use container queries for reusable components.
- Keep tap targets large and body text readable.
Common mistakes
- Forgetting the viewport meta tag.
- Designing desktop-first and piling on overrides.
- Chasing specific device breakpoints instead of content-driven ones.
- Fixed pixel widths that overflow on small screens.
- Hover-only interactions that do not work on touch.
- Testing only in a resized desktop window.
Where to go next
Responsive design is the baseline for every modern interface. Build on CSS fundamentals, use Flexbox and CSS Grid for layout, and add CSS Variables for consistent spacing and theming. Then take a page you know and resize it slowly from phone to desktop, fixing each break as you go.