Responsive Design
What is responsive design?
Responsive design means your website looks good and works well on every screen size — from a 4-inch phone to a 32-inch monitor. Instead of building separate websites for mobile and desktop, you build one site that adapts.
The viewport meta tag
This is mandatory. Without it, mobile browsers render your page as if it were a desktop site and then zoom out:
HTML
<meta name="viewport" content="width=device-width, initial-scale=1" />Mobile-first approach
Write your base CSS for mobile, then add complexity for larger screens:
CSS
/* Base: mobile (single column) */
.container {
padding: 1rem;
}
.grid {
display: flex;
flex-direction: column;
gap: 1rem;
}
/* Tablet and up */
@media (min-width: 768px) {
.grid {
flex-direction: row;
flex-wrap: wrap;
}
.grid > * {
flex: 1 1 calc(50% - 0.5rem);
}
}
/* Desktop */
@media (min-width: 1024px) {
.container {
max-width: 1200px;
margin: 0 auto;
}
.grid > * {
flex: 1 1 calc(33.333% - 0.67rem);
}
}Why mobile-first? Most CSS is about adding layout (columns, sidebars, wider spacing) as screens get bigger. Starting from mobile means your base CSS is simpler.
Common breakpoints
There's no "right" set of breakpoints, but these cover most devices:
| Breakpoint | Target |
|---|---|
| 480px | Small phones |
| 768px | Tablets |
| 1024px | Laptops |
| 1280px | Desktops |
But don't design for devices — design for your content. If a paragraph looks too wide at 600px, add a breakpoint at 600px.
Fluid typography
Instead of fixed font sizes that require media queries to change, use
clamp():CSS
h1 {
font-size: clamp(1.5rem, 4vw, 3rem);
}
p {
font-size: clamp(0.875rem, 1.5vw, 1.125rem);
}clamp(minimum, preferred, maximum) — the font scales with the viewport width but never goes below the minimum or above the maximum.Fluid spacing
The same approach works for padding and margins:
CSS
.section {
padding: clamp(2rem, 5vw, 6rem) clamp(1rem, 3vw, 4rem);
}Responsive images
CSS approach — make images fit their container:
CSS
img {
max-width: 100%;
height: auto;
}HTML approach — serve different file sizes:
HTML
<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="Description"
/>Container queries (modern CSS)
Media queries are based on the viewport width. Container queries are based on the parent element's width:
CSS
.card-container {
container-type: inline-size;
}
@container (min-width: 400px) {
.card {
display: flex;
gap: 1rem;
}
}This is powerful because the same component can adapt whether it's in a wide main area or a narrow sidebar.
Testing responsive design
- Browser DevTools — Chrome/Firefox have a responsive design mode (toggle with Ctrl+Shift+M).
- Real devices — always test on an actual phone. Emulators miss touch targets, scrolling feel, and real network speed.
- Resize your browser — drag the window edge and watch for awkward breaks.
Common responsive patterns
Hamburger menu — hide the nav behind a toggle on mobile:
CSS
.nav-links {
display: none;
}
@media (min-width: 768px) {
.nav-links {
display: flex;
}
.nav-toggle {
display: none;
}
}Stack to side-by-side — content stacks vertically on mobile, sits side-by-side on desktop:
CSS
.hero {
display: flex;
flex-direction: column;
}
@media (min-width: 768px) {
.hero {
flex-direction: row;
align-items: center;
}
}Key takeaway
Responsive design is not optional — most web traffic is mobile. Use the mobile-first approach,
clamp() for fluid sizing, media queries for layout changes, and always test on real devices. The goal is one website that works everywhere.