/ references / responsive-design.md
responsive-design.md
1 # Responsive Design System 2 3 **Purpose:** Complete guide to designing for multiple devices and screen sizes with modern, performance-first responsive design principles. 4 5 **Principle:** Mobile-first is not optional — it's the default. Design for the smallest screen first, then progressively enhance for larger screens. 6 7 --- 8 9 ## 1. Mobile-First Design Philosophy 10 11 ### Why Mobile-First? 12 13 **Principle:** Start with mobile constraints, then add complexity for larger screens. 14 15 **Benefits:** 16 - **Forces prioritization** — Mobile screen real estate is limited, so you must decide what matters 17 - **Performance first** — Mobile devices are slower and on metered connections 18 - **Touch-first** — Design for touch from the start, not as an afterthought 19 - **Progressive enhancement** — Base experience works everywhere, enhancements for capable devices 20 21 **Mobile-first process:** 22 1. Design for 320px-375px (small phones) 23 2. Test touch targets and gestures 24 3. Validate performance on slow 3G 25 4. Enhance for tablets (768px+) 26 5. Enhance for desktops (1024px+) 27 28 **Anti-pattern:** Desktop-first — designing for 1920px then "shrinking" for mobile. This creates bloated, slow mobile experiences. 29 30 --- 31 32 ## 2. Modern Breakpoint System (2024+) 33 34 ### Standard Breakpoints 35 36 **Principle:** Breakpoints should be based on content, not devices. Device sizes change; content needs don't. 37 38 ```css 39 /* Mobile-first approach */ 40 /* Default: 320px-375px (small phones) */ 41 42 /* Small tablets and large phones (640px+) */ 43 @media (min-width: 40rem) { /* 640px */ } 44 45 /* Tablets (768px+) */ 46 @media (min-width: 48rem) { /* 768px */ } 47 48 /* Small laptops and large tablets (1024px+) */ 49 @media (min-width: 64rem) { /* 1024px */ } 50 51 /* Desktops (1280px+) */ 52 @media (min-width: 80rem) { /* 1280px */ } 53 54 /* Large desktops (1536px+) */ 55 @media (min-width: 96rem) { /* 1536px */ } 56 ``` 57 58 **Why rem units?** 59 - Rem units respect user's browser font size settings 60 - Consistent scaling across the design system 61 - Better accessibility than fixed px breakpoints 62 63 **Container queries (2024+ standard):** 64 65 ```css 66 /* Container queries are better than media queries for components */ 67 @container (min-width: 400px) { 68 .card { 69 display: grid; 70 grid-template-columns: 1fr 1fr; 71 } 72 } 73 ``` 74 75 **Benefits of container queries:** 76 - Components are truly reusable 77 - Component responds to its container, not the viewport 78 - Works in any layout context 79 80 --- 81 82 ## 3. Responsive Layout Patterns 83 84 ### Pattern 1: Single Column Stack 85 86 **Mobile (default):** 87 ```css 88 .content { 89 display: flex; 90 flex-direction: column; 91 gap: 1rem; 92 } 93 ``` 94 95 **Tablet+ (768px):** 96 ```css 97 @media (min-width: 48rem) { 98 .content { 99 flex-direction: row; 100 } 101 } 102 ``` 103 104 ### Pattern 2: Holy Grail Layout 105 106 **Mobile (default):** Single column 107 **Tablet+ (768px):** Two columns (content + sidebar) 108 **Desktop+ (1024px):** Three columns (sidebar + content + sidebar) 109 110 ```css 111 /* Mobile: stacked */ 112 .holy-grail { 113 display: grid; 114 gap: 1rem; 115 } 116 117 /* Tablet: content + one sidebar */ 118 @media (min-width: 48rem) { 119 .holy-grail { 120 grid-template-columns: 1fr 3fr; 121 } 122 } 123 124 /* Desktop: both sidebars */ 125 @media (min-width: 64rem) { 126 .holy-grail { 127 grid-template-columns: 1fr 3fr 1fr; 128 } 129 } 130 ``` 131 132 ### Pattern 3: Card Grid 133 134 **Mobile (default):** 1 column 135 **Small tablet (640px):** 2 columns 136 **Tablet (768px):** 3 columns 137 **Desktop (1024px):** 4 columns 138 139 ```css 140 .card-grid { 141 display: grid; 142 gap: 1rem; 143 grid-template-columns: 1fr; 144 } 145 146 @media (min-width: 40rem) { 147 .card-grid { 148 grid-template-columns: repeat(2, 1fr); 149 } 150 } 151 152 @media (min-width: 48rem) { 153 .card-grid { 154 grid-template-columns: repeat(3, 1fr); 155 } 156 } 157 158 @media (min-width: 64rem) { 159 .card-grid { 160 grid-template-columns: repeat(4, 1fr); 161 } 162 } 163 ``` 164 165 **Better approach with auto-fit:** 166 167 ```css 168 .card-grid { 169 display: grid; 170 gap: 1rem; 171 /* Automatically adjusts based on available space */ 172 grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); 173 } 174 ``` 175 176 ### Pattern 4: Navigation 177 178 **Mobile:** Hamburger menu or bottom tab bar 179 **Tablet+:** Horizontal navigation 180 181 ```css 182 /* Mobile: hidden by default */ 183 .nav-links { 184 display: none; 185 } 186 187 @media (min-width: 64rem) { 188 .nav-links { 189 display: flex; 190 gap: 2rem; 191 } 192 } 193 ``` 194 195 --- 196 197 ## 4. Touch Targets and Interactions 198 199 ### Minimum Touch Target Size 200 201 **Principle:** Touch targets must be large enough for reliable interaction. 202 203 **Minimum sizes:** 204 - **Buttons/links:** 44×44px minimum (iOS) / 48×48px (Android) 205 - **Checkboxes/radios:** 44×44px tap area (visual element can be smaller) 206 - **Form inputs:** 48px height minimum 207 208 **Best practices:** 209 ```css 210 /* Bad: too small */ 211 button { 212 padding: 0.25rem 0.5rem; /* ~14px height */ 213 } 214 215 /* Good: meets guidelines */ 216 button { 217 padding: 0.75rem 1rem; /* ~48px height */ 218 min-height: 44px; 219 } 220 221 /* Better: spacious + visual feedback */ 222 button { 223 padding: 0.875rem 1.5rem; /* ~56px height */ 224 min-height: 48px; 225 transition: transform 0.1s; 226 } 227 228 button:active { 229 transform: scale(0.98); 230 } 231 ``` 232 233 ### Spacing Between Touch Targets 234 235 **Principle:** Touch targets need breathing room to prevent accidental taps. 236 237 **Minimum spacing:** 8px between targets 238 239 ```css 240 .button-group { 241 display: flex; 242 gap: 0.5rem; /* 8px */ 243 } 244 ``` 245 246 ### Thumb Zone Design 247 248 **Principle:** Place primary actions in the "thumb zone" (bottom of screen for phones). 249 250 **Mobile layout:** 251 - **Primary actions:** Bottom of screen (easy thumb reach) 252 - **Secondary actions:** Top of screen (requires stretching) 253 - **Dangerous actions:** Top-left or require confirmation (harder to tap accidentally) 254 255 **Example:** 256 ``` 257 ┌─────────────────┐ 258 │ Header │ ← Secondary (save, cancel) 259 ├─────────────────┤ 260 │ │ 261 │ Content │ 262 │ │ 263 ├─────────────────┤ 264 │ Primary CTA │ ← Primary (submit, next) 265 └─────────────────┘ 266 ``` 267 268 --- 269 270 ## 5. Responsive Typography 271 272 ### Fluid Typography 273 274 **Principle:** Typography should scale smoothly between breakpoints, not jump. 275 276 **Old way (fixed sizes):** 277 ```css 278 h1 { font-size: 2rem; } /* 32px */ 279 @media (min-width: 64rem) { 280 h1 { font-size: 3rem; } /* 48px - jump! */ 281 } 282 ``` 283 284 **Modern way (fluid scaling):** 285 ```css 286 /* Scales from 2rem at 320px to 3rem at 1200px */ 287 h1 { 288 font-size: clamp(2rem, 5vw + 1rem, 3rem); 289 } 290 ``` 291 292 **How clamp() works:** 293 - Minimum: 2rem (never smaller) 294 - Preferred: 5vw + 1rem (scales with viewport) 295 - Maximum: 3rem (never larger) 296 297 **Line height also scales:** 298 ```css 299 body { 300 font-size: clamp(1rem, 0.5vw + 0.875rem, 1.125rem); 301 line-height: clamp(1.5, 0.5vw + 1.4, 1.7); 302 } 303 ``` 304 305 ### Responsive Type Scale 306 307 **Mobile (default):** 308 ```css 309 --font-size-xs: 0.75rem; /* 12px */ 310 --font-size-sm: 0.875rem; /* 14px */ 311 --font-size-base: 1rem; /* 16px */ 312 --font-size-lg: 1.125rem; /* 18px */ 313 --font-size-xl: 1.25rem; /* 20px */ 314 --font-size-2xl: 1.5rem; /* 24px */ 315 --font-size-3xl: 1.875rem; /* 30px */ 316 ``` 317 318 **Desktop (1024px+):** 319 ```css 320 @media (min-width: 64rem) { 321 :root { 322 --font-size-xs: 0.875rem; /* 14px */ 323 --font-size-sm: 1rem; /* 16px */ 324 --font-size-base: 1.125rem; /* 18px */ 325 --font-size-lg: 1.25rem; /* 20px */ 326 --font-size-xl: 1.5rem; /* 24px */ 327 --font-size-2xl: 1.875rem; /* 30px */ 328 --font-size-3xl: 2.25rem; /* 36px */ 329 } 330 } 331 ``` 332 333 --- 334 335 ## 6. Responsive Images 336 337 ### srcset for Art Direction 338 339 **Principle:** Serve different image crops for different screen sizes. 340 341 ```html 342 <img 343 src="image-800.jpg" 344 srcset=" 345 image-400.jpg 400w, 346 image-800.jpg 800w, 347 image-1200.jpg 1200w, 348 image-1600.jpg 1600w 349 " 350 sizes=" 351 (max-width: 640px) 100vw, 352 (max-width: 1024px) 50vw, 353 33vw 354 " 355 alt="Responsive image" 356 > 357 ``` 358 359 **How sizes works:** 360 - On mobile (≤640px): image takes 100% of viewport width 361 - On tablet (≤1024px): image takes 50% of viewport width 362 - On desktop (>1024px): image takes 33% of viewport width (3-column grid) 363 364 **Browser calculates:** 365 - Mobile (375px viewport): 375px × 1 = 375px → loads `image-400.jpg` 366 - Tablet (768px viewport): 768px × 0.5 = 384px → loads `image-400.jpg` 367 - Desktop (1440px viewport): 1440px × 0.33 = 475px → loads `image-800.jpg` 368 369 ### Modern Image Formats 370 371 **Use WebP with JPEG fallback:** 372 373 ```html 374 <picture> 375 <source srcset="image.webp" type="image/webp"> 376 <img src="image.jpg" alt="Description"> 377 </picture> 378 ``` 379 380 **Benefits:** 381 - WebP is 25-35% smaller than JPEG 382 - Same quality, smaller file size 383 - Better performance on slow connections 384 385 ### Lazy Loading 386 387 **Always lazy load images below the fold:** 388 389 ```html 390 <img src="image.jpg" loading="lazy" alt="Description"> 391 ``` 392 393 **Benefits:** 394 - Reduces initial page load 395 - Saves bandwidth 396 - Improves Time to Interactive (TTI) 397 398 --- 399 400 ## 7. Responsive Spacing System 401 402 ### Vertical Rhythm 403 404 **Principle:** Use consistent vertical spacing that scales across devices. 405 406 **Mobile spacing:** 407 ```css 408 :root { 409 --space-1: 0.25rem; /* 4px */ 410 --space-2: 0.5rem; /* 8px */ 411 --space-3: 0.75rem; /* 12px */ 412 --space-4: 1rem; /* 16px */ 413 --space-5: 1.5rem; /* 24px */ 414 --space-6: 2rem; /* 32px */ 415 --space-7: 2.5rem; /* 40px */ 416 --space-8: 3rem; /* 48px */ 417 } 418 ``` 419 420 **Desktop spacing (increase for larger screens):** 421 ```css 422 @media (min-width: 64rem) { 423 :root { 424 --space-1: 0.25rem; /* 4px */ 425 --space-2: 0.5rem; /* 8px */ 426 --space-3: 0.75rem; /* 12px */ 427 --space-4: 1rem; /* 16px */ 428 --space-5: 2rem; /* 32px - was 24px */ 429 --space-6: 2.5rem; /* 40px - was 32px */ 430 --space-7: 3rem; /* 48px - was 40px */ 431 --space-8: 4rem; /* 64px - was 48px */ 432 } 433 } 434 ``` 435 436 **Container padding:** 437 438 ```css 439 /* Mobile: less padding */ 440 .container { 441 padding: 0 1rem; 442 } 443 444 /* Tablet: more padding */ 445 @media (min-width: 48rem) { 446 .container { 447 padding: 0 2rem; 448 } 449 } 450 451 /* Desktop: max width + centered */ 452 @media (min-width: 64rem) { 453 .container { 454 max-width: 1200px; 455 margin: 0 auto; 456 padding: 0 2rem; 457 } 458 } 459 ``` 460 461 --- 462 463 ## 8. Cross-Device Considerations 464 465 ### Hover vs Touch 466 467 **Problem:** Hover states don't work on touch devices. 468 469 **Solution:** Design for touch first, enhance with hover. 470 471 ```css 472 /* Base: visible by default (touch) */ 473 .tooltip { 474 opacity: 1; 475 } 476 477 /* Desktop: hide until hover */ 478 @media (hover: hover) { 479 .tooltip { 480 opacity: 0; 481 transition: opacity 0.2s; 482 } 483 484 .tooltip-trigger:hover .tooltip { 485 opacity: 1; 486 } 487 } 488 ``` 489 490 ### Device-Specific Features 491 492 **Detect touch capability:** 493 494 ```css 495 @media (hover: none) and (pointer: coarse) { 496 /* Touch device: larger touch targets */ 497 button { 498 min-height: 48px; 499 min-width: 48px; 500 } 501 } 502 503 @media (hover: hover) and (pointer: fine) { 504 /* Mouse/trackpad: smaller targets OK */ 505 button { 506 min-height: 36px; 507 min-width: 36px; 508 } 509 } 510 ``` 511 512 **Dark mode support:** 513 514 ```css 515 @media (prefers-color-scheme: dark) { 516 :root { 517 --bg-primary: #0a0a0a; 518 --text-primary: #fafafa; 519 } 520 } 521 522 @media (prefers-color-scheme: light) { 523 :root { 524 --bg-primary: #ffffff; 525 --text-primary: #171717; 526 } 527 } 528 ``` 529 530 **Reduced motion support:** 531 532 ```css 533 @media (prefers-reduced-motion: reduce) { 534 * { 535 animation-duration: 0.01ms !important; 536 transition-duration: 0.01ms !important; 537 } 538 } 539 ``` 540 541 --- 542 543 ## 9. Performance for Responsive Design 544 545 ### Mobile Performance Budgets 546 547 **Principle:** Mobile devices are slower and on metered connections. 548 549 **Budgets:** 550 - **Initial page weight:** < 1MB (ideally < 500KB) 551 - **Initial JS:** < 200KB gzipped 552 - **Time to Interactive:** < 5 seconds on 3G 553 - **First Contentful Paint:** < 2 seconds on 3G 554 555 ### Critical CSS 556 557 **Inline CSS for above-the-fold content:** 558 559 ```html 560 <style> 561 /* Critical CSS for hero section */ 562 .hero { 563 display: flex; 564 align-items: center; 565 min-height: 50vh; 566 } 567 </style> 568 569 <!-- Rest of CSS loaded async --> 570 <link rel="preload" href="styles.css" as="style" onload="this.onload=null;this.rel='stylesheet'"> 571 ``` 572 573 ### Font Loading Strategy 574 575 ```html 576 <!-- Preconnect to font domain --> 577 <link rel="preconnect" href="https://fonts.googleapis.com"> 578 <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> 579 580 <!-- Load fonts with font-display --> 581 <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600&display=swap" rel="stylesheet"> 582 ``` 583 584 **font-display: swap** shows text immediately, swaps in font when loaded. 585 586 --- 587 588 ## 10. Testing Responsive Design 589 590 ### Device Testing 591 592 **Essential devices to test:** 593 - **Small phone:** iPhone SE (375×667) or Android small (360×640) 594 - **Large phone:** iPhone 14 Pro Max (430×932) or Android large (412×915) 595 - **Tablet:** iPad (768×1024) or Android tablet (800×1280) 596 - **Laptop:** 1366×768 (common laptop resolution) 597 - **Desktop:** 1920×1080 (common desktop) 598 599 ### Browser DevTools 600 601 **Chrome DevTools:** 602 1. Open DevTools (Cmd+Option+I) 603 2. Click device toolbar (Cmd+Shift+M) 604 3. Select device from dropdown or enter custom dimensions 605 4. Test throttling (Network tab → Throttling → Fast 3G) 606 607 **Test checklist:** 608 - [ ] Layout doesn't break at any breakpoint 609 - [ ] Text is readable without zooming 610 - [ ] Touch targets are large enough (44×44px minimum) 611 - [ ] No horizontal scrolling 612 - [ ] Images load appropriate sizes 613 - [ ] Navigation works on all devices 614 - [ ] Forms are easy to complete on mobile 615 - [ ] Performance is acceptable on 3G 616 617 ### Real-Device Testing 618 619 **Why:** Emulators aren't perfect. 620 621 **Tools:** 622 - **BrowserStack:** Cross-browser testing 623 - **LambdaTest:** Real device cloud 624 - **Physical devices:** Test on actual phones/tablets 625 626 --- 627 628 ## 11. Common Responsive Design Mistakes 629 630 ### 1. Designing Desktop-First 631 632 **Problem:** Designing for 1920px, then "shrinking" for mobile. 633 634 **Solution:** Always design mobile-first. Start with 320px-375px. 635 636 ### 2. Too Many Breakpoints 637 638 **Problem:** Breakpoint at every 100px. 639 640 **Solution:** Use 3-5 breakpoints max. Let content decide breakpoints, not arbitrary numbers. 641 642 ### 3. Hiding Content on Mobile 643 644 **Problem:** "This doesn't fit, let's hide it on mobile." 645 646 **Solution:** Reorganize and prioritize content. If it's important enough for desktop, it's important for mobile. 647 648 ### 4. Fixed Width Containers 649 650 **Problem:** `width: 1200px` breaks on smaller screens. 651 652 **Solution:** Use `max-width: 1200px` with `width: 100%`. 653 654 ### 5. Tiny Touch Targets 655 656 **Problem:** 16px buttons on mobile. 657 658 **Solution:** Minimum 44×44px for all touch targets. 659 660 ### 6. Horizontal Scroll 661 662 **Problem:** Content wider than viewport causes horizontal scroll. 663 664 **Solution:** Use `overflow-x: hidden` on body and ensure all containers use percentage/max-width. 665 666 ### 7. Heavy Images on Mobile 667 668 **Problem:** Loading 4000px wide images on 375px screens. 669 670 **Solution:** Use `srcset` and `sizes` to serve appropriate image sizes. 671 672 --- 673 674 ## 12. Responsive Design Checklist 675 676 ### Planning Phase 677 678 - [ ] Define target devices and breakpoints 679 - [ ] Create content priority list (what's essential on mobile?) 680 - [ ] Set performance budgets 681 - [ ] Plan navigation strategy (hamburger vs tabs) 682 683 ### Design Phase 684 685 - [ ] Start with mobile design (320-375px) 686 - [ ] Design touch targets minimum 44×44px 687 - [ ] Use relative units (rem, %, vw/vh) 688 - [ ] Plan how layout expands at breakpoints 689 - [ ] Design typography scale for each breakpoint 690 691 ### Development Phase 692 693 - [ ] Implement mobile-first CSS 694 - [ ] Use container queries for components 695 - [ ] Implement responsive images (srcset) 696 - [ ] Lazy load images below fold 697 - [ ] Test on real devices 698 - [ ] Validate performance on 3G 699 700 ### Testing Phase 701 702 - [ ] Test on small phone (375px) 703 - [ ] Test on large phone (430px) 704 - [ ] Test on tablet (768px) 705 - [ ] Test on laptop (1366px) 706 - [ ] Test on desktop (1920px) 707 - [ ] Test touch interactions 708 - [ ] Test keyboard navigation 709 - [ ] Test with screen reader 710 - [ ] Test on slow connection (3G) 711 712 --- 713 714 ## 13. Tools and Resources 715 716 **Testing tools:** 717 - Chrome DevTools device emulator 718 - Firefox Responsive Design Mode 719 - BrowserStack (cross-browser testing) 720 - LambdaTest (real device cloud) 721 722 **Performance tools:** 723 - Lighthouse (built into Chrome) 724 - WebPageTest (detailed performance analysis) 725 - PageSpeed Insights (Google's performance tool) 726 727 **Design tools:** 728 - Figma (built-in responsive design features) 729 - Sketch (responsive design features) 730 731 **Code examples:** 732 - MDN Responsive Design: https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Responsive_Design 733 - CSS Tricks: A Complete Guide to CSS Flexbox 734 - CSS Tricks: A Complete Guide to CSS Grid 735 736 **Frameworks:** 737 - Tailwind CSS (responsive utilities) 738 - Bootstrap (responsive grid system) 739 - CSS Grid (native responsive layout) 740 741 --- 742 743 ## Quick Reference 744 745 ### Breakpoints (2024+) 746 747 ```css 748 /* Mobile-first approach */ 749 /* Default: 320px-375px */ 750 @media (min-width: 40rem) { /* 640px */ } 751 @media (min-width: 48rem) { /* 768px */ } 752 @media (min-width: 64rem) { /* 1024px */ } 753 @media (min-width: 80rem) { /* 1280px */ } 754 @media (min-width: 96rem) { /* 1536px */ } 755 ``` 756 757 ### Touch Targets 758 759 ```css 760 /* Minimum sizes */ 761 button, a, input { 762 min-width: 44px; 763 min-height: 44px; 764 } 765 ``` 766 767 ### Responsive Images 768 769 ```html 770 <img 771 src="image-800.jpg" 772 srcset="image-400.jpg 400w, image-800.jpg 800w, image-1200.jpg 1200w" 773 sizes="(max-width: 640px) 100vw, 50vw" 774 loading="lazy" 775 alt="Description" 776 > 777 ``` 778 779 ### Container Queries (2024+) 780 781 ```css 782 @container (min-width: 400px) { 783 .card { 784 display: grid; 785 grid-template-columns: 1fr 1fr; 786 } 787 } 788 ``` 789 790 --- 791 792 **Remember:** Responsive design is not just about making things fit. It's about creating optimal experiences for every device, every context, and every user. 793 794 **Mobile-first is not optional — it's the default.**