3.4 KiB
Responsive Design
Mobile-First: Write It Right
Start with base styles for mobile, use min-width queries to layer complexity. Desktop-first (max-width) means mobile loads unnecessary styles first.
Breakpoints: Content-Driven
Don't chase device sizes—let content tell you where to break. Start narrow, stretch until design breaks, add breakpoint there. Three breakpoints usually suffice (640, 768, 1024px). Use clamp() for fluid values without breakpoints.
Detect Input Method, Not Just Screen Size
Screen size doesn't tell you input method. A laptop with touchscreen, a tablet with keyboard—use pointer and hover queries:
/* Fine pointer (mouse, trackpad) */
@media (pointer: fine) {
.button { padding: 8px 16px; }
}
/* Coarse pointer (touch, stylus) */
@media (pointer: coarse) {
.button { padding: 12px 20px; } /* Larger touch target */
}
/* Device supports hover */
@media (hover: hover) {
.card:hover { transform: translateY(-2px); }
}
/* Device doesn't support hover (touch) */
@media (hover: none) {
.card { /* No hover state - use active instead */ }
}
Critical: Don't rely on hover for functionality. Touch users can't hover.
Safe Areas: Handle the Notch
Modern phones have notches, rounded corners, and home indicators. Use env():
body {
padding-top: env(safe-area-inset-top);
padding-bottom: env(safe-area-inset-bottom);
padding-left: env(safe-area-inset-left);
padding-right: env(safe-area-inset-right);
}
/* With fallback */
.footer {
padding-bottom: max(1rem, env(safe-area-inset-bottom));
}
Enable viewport-fit in your meta tag:
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
Responsive Images: Get It Right
srcset with Width Descriptors
<img
src="hero-800.jpg"
srcset="
hero-400.jpg 400w,
hero-800.jpg 800w,
hero-1200.jpg 1200w
"
sizes="(max-width: 768px) 100vw, 50vw"
alt="Hero image"
>
How it works:
srcsetlists available images with their actual widths (wdescriptors)sizestells the browser how wide the image will display- Browser picks the best file based on viewport width AND device pixel ratio
Picture Element for Art Direction
When you need different crops/compositions (not just resolutions):
<picture>
<source media="(min-width: 768px)" srcset="wide.jpg">
<source media="(max-width: 767px)" srcset="tall.jpg">
<img src="fallback.jpg" alt="...">
</picture>
Layout Adaptation Patterns
Navigation: Three stages—hamburger + drawer on mobile, horizontal compact on tablet, full with labels on desktop. Tables: Transform to cards on mobile using display: block and data-label attributes. Progressive disclosure: Use <details>/<summary> for content that can collapse on mobile.
Testing: Don't Trust DevTools Alone
DevTools device emulation is useful for layout but misses:
- Actual touch interactions
- Real CPU/memory constraints
- Network latency patterns
- Font rendering differences
- Browser chrome/keyboard appearances
Test on at least: One real iPhone, one real Android, a tablet if relevant. Cheap Android phones reveal performance issues you'll never see on simulators.
Avoid: Desktop-first design. Device detection instead of feature detection. Separate mobile/desktop codebases. Ignoring tablet and landscape. Assuming all mobile devices are powerful.