Back to Blog
Responsive DesignMobileCSSWeb Development

Mobile-First Responsive Design Strategies

Design for mobile first, then scale up. From fluid layouts to responsive images to touch interactions.

B
Bootspring Team
Engineering
July 5, 2024
5 min read

Mobile-first means designing for the smallest screen first, then progressively enhancing for larger screens. It forces focus on essential content and improves performance.

Why Mobile First?#

Benefits: ✓ Forces content prioritization ✓ Better performance (load less, enhance more) ✓ Easier to scale up than scale down ✓ Mobile traffic often exceeds desktop ✓ Progressive enhancement philosophy

Media Query Strategy#

Mobile First (min-width)#

1/* Base styles (mobile) */ 2.container { 3 padding: 1rem; 4 width: 100%; 5} 6 7/* Tablet and up */ 8@media (min-width: 768px) { 9 .container { 10 padding: 2rem; 11 max-width: 720px; 12 margin: 0 auto; 13 } 14} 15 16/* Desktop and up */ 17@media (min-width: 1024px) { 18 .container { 19 max-width: 960px; 20 } 21} 22 23/* Large desktop */ 24@media (min-width: 1280px) { 25 .container { 26 max-width: 1200px; 27 } 28}

Breakpoint System#

1:root { 2 /* Breakpoints */ 3 --bp-sm: 640px; 4 --bp-md: 768px; 5 --bp-lg: 1024px; 6 --bp-xl: 1280px; 7 --bp-2xl: 1536px; 8} 9 10/* Mixins with CSS custom properties aren't possible, 11 but here's the conceptual approach */ 12 13/* Small phones: 0 - 639px (base styles) */ 14/* Large phones: 640px+ */ 15/* Tablets: 768px+ */ 16/* Laptops: 1024px+ */ 17/* Desktops: 1280px+ */ 18/* Large screens: 1536px+ */

Fluid Typography#

1/* Fluid font sizes */ 2html { 3 /* Minimum 16px, maximum 20px, scales with viewport */ 4 font-size: clamp(1rem, 0.875rem + 0.5vw, 1.25rem); 5} 6 7h1 { 8 /* Minimum 2rem, maximum 4rem */ 9 font-size: clamp(2rem, 1.5rem + 2vw, 4rem); 10} 11 12h2 { 13 font-size: clamp(1.5rem, 1.25rem + 1.5vw, 3rem); 14} 15 16/* Line height that adapts */ 17p { 18 line-height: calc(1.5em + 0.5vw); 19}

Fluid Spacing#

1:root { 2 --space-xs: clamp(0.25rem, 0.2rem + 0.25vw, 0.5rem); 3 --space-sm: clamp(0.5rem, 0.4rem + 0.5vw, 1rem); 4 --space-md: clamp(1rem, 0.8rem + 1vw, 2rem); 5 --space-lg: clamp(2rem, 1.5rem + 2vw, 4rem); 6 --space-xl: clamp(4rem, 3rem + 4vw, 8rem); 7} 8 9.section { 10 padding: var(--space-lg) var(--space-md); 11} 12 13.card { 14 padding: var(--space-md); 15 margin-bottom: var(--space-sm); 16}

Responsive Layouts#

CSS Grid#

1/* Auto-fit grid */ 2.grid { 3 display: grid; 4 grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); 5 gap: 1.5rem; 6} 7 8/* Named areas that change */ 9.layout { 10 display: grid; 11 grid-template-areas: 12 "header" 13 "main" 14 "sidebar" 15 "footer"; 16 gap: 1rem; 17} 18 19@media (min-width: 768px) { 20 .layout { 21 grid-template-areas: 22 "header header" 23 "sidebar main" 24 "footer footer"; 25 grid-template-columns: 250px 1fr; 26 } 27}

Flexbox#

1.nav { 2 display: flex; 3 flex-direction: column; 4 gap: 0.5rem; 5} 6 7@media (min-width: 768px) { 8 .nav { 9 flex-direction: row; 10 gap: 2rem; 11 } 12} 13 14/* Responsive cards */ 15.card-container { 16 display: flex; 17 flex-wrap: wrap; 18 gap: 1rem; 19} 20 21.card { 22 flex: 1 1 300px; /* Grow, shrink, basis */ 23 max-width: 100%; 24}

Responsive Images#

1<!-- Art direction with picture --> 2<picture> 3 <source media="(min-width: 1024px)" srcset="hero-desktop.jpg"> 4 <source media="(min-width: 768px)" srcset="hero-tablet.jpg"> 5 <img src="hero-mobile.jpg" alt="Hero image"> 6</picture> 7 8<!-- Resolution switching --> 9<img 10 src="image-400.jpg" 11 srcset=" 12 image-400.jpg 400w, 13 image-800.jpg 800w, 14 image-1200.jpg 1200w 15 " 16 sizes=" 17 (min-width: 1024px) 33vw, 18 (min-width: 768px) 50vw, 19 100vw 20 " 21 alt="Responsive image" 22>
1/* Fluid images */ 2img { 3 max-width: 100%; 4 height: auto; 5} 6 7/* Object fit for containers */ 8.image-container { 9 aspect-ratio: 16 / 9; 10} 11 12.image-container img { 13 width: 100%; 14 height: 100%; 15 object-fit: cover; 16}

Touch Interactions#

1/* Larger touch targets */ 2.button { 3 min-height: 44px; /* Apple's recommendation */ 4 min-width: 44px; 5 padding: 12px 24px; 6} 7 8/* Touch-friendly spacing */ 9.nav-link { 10 padding: 12px 16px; 11 display: block; 12} 13 14/* Remove hover on touch devices */ 15@media (hover: none) { 16 .button:hover { 17 /* Don't apply hover styles */ 18 background-color: initial; 19 } 20} 21 22/* Hover only on devices that support it */ 23@media (hover: hover) { 24 .button:hover { 25 background-color: var(--color-primary-dark); 26 } 27}
1/* Mobile hamburger menu */ 2.nav-toggle { 3 display: block; 4} 5 6.nav-menu { 7 position: fixed; 8 top: 0; 9 left: -100%; 10 width: 80%; 11 height: 100vh; 12 transition: left 0.3s ease; 13} 14 15.nav-menu.active { 16 left: 0; 17} 18 19@media (min-width: 768px) { 20 .nav-toggle { 21 display: none; 22 } 23 24 .nav-menu { 25 position: static; 26 width: auto; 27 height: auto; 28 display: flex; 29 } 30}

Performance Considerations#

1<!-- Lazy load images --> 2<img src="image.jpg" loading="lazy" alt="Lazy loaded"> 3 4<!-- Preload critical resources --> 5<link rel="preload" href="hero-mobile.jpg" as="image" media="(max-width: 767px)"> 6<link rel="preload" href="hero-desktop.jpg" as="image" media="(min-width: 768px)">
1/* Reduce motion for accessibility */ 2@media (prefers-reduced-motion: reduce) { 3 *, 4 *::before, 5 *::after { 6 animation-duration: 0.01ms !important; 7 transition-duration: 0.01ms !important; 8 } 9}

Testing Checklist#

Device Testing: - [ ] iPhone SE (375px) - [ ] iPhone 14 (390px) - [ ] iPad (768px) - [ ] iPad Pro (1024px) - [ ] Laptop (1280px) - [ ] Desktop (1920px) Interactions: - [ ] Touch targets 44px+ - [ ] No hover-dependent features - [ ] Swipe gestures work - [ ] Forms are mobile-friendly Performance: - [ ] Images optimized - [ ] Fonts subset - [ ] CSS/JS minimal - [ ] Core Web Vitals passing

Conclusion#

Mobile-first is a mindset, not just a technique. Start with constraints, focus on content, and progressively enhance.

The result is faster sites that work everywhere and serve everyone.

Share this article

Help spread the word about Bootspring