| 1 | # Responsive Design |
| 2 | |
| 3 | ## Mobile-First: Write It Right |
| 4 | |
| 5 | Start with base styles for mobile, use `min-width` queries to layer complexity. Desktop-first (`max-width`) means mobile loads unnecessary styles first. |
| 6 | |
| 7 | ## Breakpoints: Content-Driven |
| 8 | |
| 9 | 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. |
| 10 | |
| 11 | ## Detect Input Method, Not Just Screen Size |
| 12 | |
| 13 | **Screen size doesn't tell you input method.** A laptop with touchscreen, a tablet with keyboard. Use pointer and hover queries: |
| 14 | |
| 15 | ```css |
| 16 | /* Fine pointer (mouse, trackpad) */ |
| 17 | @media (pointer: fine) { |
| 18 | .button { padding: 8px 16px; } |
| 19 | } |
| 20 | |
| 21 | /* Coarse pointer (touch, stylus) */ |
| 22 | @media (pointer: coarse) { |
| 23 | .button { padding: 12px 20px; } /* Larger touch target */ |
| 24 | } |
| 25 | |
| 26 | /* Device supports hover */ |
| 27 | @media (hover: hover) { |
| 28 | .card:hover { transform: translateY(-2px); } |
| 29 | } |
| 30 | |
| 31 | /* Device doesn't support hover (touch) */ |
| 32 | @media (hover: none) { |
| 33 | .card { /* No hover state - use active instead */ } |
| 34 | } |
| 35 | ``` |
| 36 | |
| 37 | **Critical**: Don't rely on hover for functionality. Touch users can't hover. |
| 38 | |
| 39 | ## Safe Areas: Handle the Notch |
| 40 | |
| 41 | Modern phones have notches, rounded corners, and home indicators. Use `env()`: |
| 42 | |
| 43 | ```css |
| 44 | body { |
| 45 | padding-top: env(safe-area-inset-top); |
| 46 | padding-bottom: env(safe-area-inset-bottom); |
| 47 | padding-left: env(safe-area-inset-left); |
| 48 | padding-right: env(safe-area-inset-right); |
| 49 | } |
| 50 | |
| 51 | /* With fallback */ |
| 52 | .footer { |
| 53 | padding-bottom: max(1rem, env(safe-area-inset-bottom)); |
| 54 | } |
| 55 | ``` |
| 56 | |
| 57 | **Enable viewport-fit** in your meta tag: |
| 58 | ```html |
| 59 | <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover"> |
| 60 | ``` |
| 61 | |
| 62 | ## Responsive Images: Get It Right |
| 63 | |
| 64 | ### srcset with Width Descriptors |
| 65 | |
| 66 | ```html |
| 67 | <img |
| 68 | src="hero-800.jpg" |
| 69 | srcset=" |
| 70 | hero-400.jpg 400w, |
| 71 | hero-800.jpg 800w, |
| 72 | hero-1200.jpg 1200w |
| 73 | " |
| 74 | sizes="(max-width: 768px) 100vw, 50vw" |
| 75 | alt="Hero image" |
| 76 | > |
| 77 | ``` |
| 78 | |
| 79 | **How it works**: |
| 80 | - `srcset` lists available images with their actual widths (`w` descriptors) |
| 81 | - `sizes` tells the browser how wide the image will display |
| 82 | - Browser picks the best file based on viewport width AND device pixel ratio |
| 83 | |
| 84 | ### Picture Element for Art Direction |
| 85 | |
| 86 | When you need different crops/compositions (not just resolutions): |
| 87 | |
| 88 | ```html |
| 89 | <picture> |
| 90 | <source media="(min-width: 768px)" srcset="wide.jpg"> |
| 91 | <source media="(max-width: 767px)" srcset="tall.jpg"> |
| 92 | <img src="fallback.jpg" alt="..."> |
| 93 | </picture> |
| 94 | ``` |
| 95 | |
| 96 | ## Layout Adaptation Patterns |
| 97 | |
| 98 | **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. |
| 99 | |
| 100 | ## Testing: Don't Trust DevTools Alone |
| 101 | |
| 102 | DevTools device emulation is useful for layout but misses: |
| 103 | |
| 104 | - Actual touch interactions |
| 105 | - Real CPU/memory constraints |
| 106 | - Network latency patterns |
| 107 | - Font rendering differences |
| 108 | - Browser chrome/keyboard appearances |
| 109 | |
| 110 | **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. |
| 111 | |
| 112 | --- |
| 113 | |
| 114 | **Avoid**: Desktop-first design. Device detection instead of feature detection. Separate mobile/desktop codebases. Ignoring tablet and landscape. Assuming all mobile devices are powerful. |
| 115 |