Back to Blog
CSSResponsive DesignFlexboxGrid

Responsive Design Patterns with CSS

Build responsive layouts effectively. From flexbox to grid to container queries and modern techniques.

B
Bootspring Team
Engineering
June 15, 2022
5 min read

Responsive design ensures your site works across all devices. Here are modern patterns for building flexible layouts.

Mobile-First Approach#

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

Flexbox Patterns#

1/* Flexible card grid */ 2.card-grid { 3 display: flex; 4 flex-wrap: wrap; 5 gap: 1rem; 6} 7 8.card { 9 flex: 1 1 300px; /* Grow, shrink, basis */ 10 max-width: 100%; 11} 12 13/* Responsive navigation */ 14.nav { 15 display: flex; 16 flex-direction: column; 17 gap: 0.5rem; 18} 19 20@media (min-width: 768px) { 21 .nav { 22 flex-direction: row; 23 justify-content: space-between; 24 align-items: center; 25 } 26} 27 28/* Centered content with sticky footer */ 29.page { 30 display: flex; 31 flex-direction: column; 32 min-height: 100vh; 33} 34 35.main { 36 flex: 1; 37} 38 39.footer { 40 margin-top: auto; 41} 42 43/* Holy grail layout */ 44.holy-grail { 45 display: flex; 46 flex-wrap: wrap; 47} 48 49.sidebar-left { 50 flex: 0 0 200px; 51 order: 1; 52} 53 54.content { 55 flex: 1; 56 min-width: 0; 57 order: 2; 58} 59 60.sidebar-right { 61 flex: 0 0 200px; 62 order: 3; 63} 64 65@media (max-width: 768px) { 66 .sidebar-left, 67 .sidebar-right { 68 flex: 0 0 100%; 69 } 70 71 .sidebar-left { 72 order: 1; 73 } 74 75 .content { 76 order: 2; 77 } 78 79 .sidebar-right { 80 order: 3; 81 } 82}

CSS Grid Patterns#

1/* Auto-fit responsive grid */ 2.grid { 3 display: grid; 4 grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); 5 gap: 1rem; 6} 7 8/* Auto-fill for empty cells */ 9.grid-fill { 10 display: grid; 11 grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); 12 gap: 1rem; 13} 14 15/* Complex dashboard layout */ 16.dashboard { 17 display: grid; 18 grid-template-areas: 19 "header header" 20 "sidebar main" 21 "footer footer"; 22 grid-template-columns: 250px 1fr; 23 grid-template-rows: auto 1fr auto; 24 min-height: 100vh; 25} 26 27.header { grid-area: header; } 28.sidebar { grid-area: sidebar; } 29.main { grid-area: main; } 30.footer { grid-area: footer; } 31 32@media (max-width: 768px) { 33 .dashboard { 34 grid-template-areas: 35 "header" 36 "main" 37 "sidebar" 38 "footer"; 39 grid-template-columns: 1fr; 40 } 41} 42 43/* Magazine layout */ 44.magazine { 45 display: grid; 46 grid-template-columns: repeat(4, 1fr); 47 grid-auto-rows: 200px; 48 gap: 1rem; 49} 50 51.magazine .featured { 52 grid-column: span 2; 53 grid-row: span 2; 54} 55 56.magazine .wide { 57 grid-column: span 2; 58} 59 60@media (max-width: 768px) { 61 .magazine { 62 grid-template-columns: 1fr; 63 grid-auto-rows: auto; 64 } 65 66 .magazine .featured, 67 .magazine .wide { 68 grid-column: span 1; 69 grid-row: span 1; 70 } 71}

Container Queries#

1/* Modern container queries */ 2.card-container { 3 container-type: inline-size; 4 container-name: card; 5} 6 7.card { 8 display: flex; 9 flex-direction: column; 10} 11 12@container card (min-width: 400px) { 13 .card { 14 flex-direction: row; 15 } 16 17 .card-image { 18 width: 40%; 19 } 20 21 .card-content { 22 width: 60%; 23 } 24} 25 26@container card (min-width: 600px) { 27 .card-title { 28 font-size: 1.5rem; 29 } 30 31 .card-actions { 32 display: flex; 33 gap: 1rem; 34 } 35}

Fluid Typography#

1/* Clamp for fluid sizing */ 2.heading { 3 /* min, preferred, max */ 4 font-size: clamp(1.5rem, 4vw, 3rem); 5} 6 7.body { 8 font-size: clamp(1rem, 2vw + 0.5rem, 1.25rem); 9} 10 11/* Fluid spacing */ 12.section { 13 padding: clamp(2rem, 5vw, 6rem); 14} 15 16/* CSS custom properties for responsive values */ 17:root { 18 --space-sm: clamp(0.5rem, 1vw, 1rem); 19 --space-md: clamp(1rem, 2vw, 2rem); 20 --space-lg: clamp(2rem, 4vw, 4rem); 21 22 --font-sm: clamp(0.875rem, 1.5vw, 1rem); 23 --font-md: clamp(1rem, 2vw, 1.25rem); 24 --font-lg: clamp(1.5rem, 3vw, 2.5rem); 25} 26 27.card { 28 padding: var(--space-md); 29} 30 31.card-title { 32 font-size: var(--font-lg); 33 margin-bottom: var(--space-sm); 34}

Responsive Images#

1/* Responsive images */ 2img { 3 max-width: 100%; 4 height: auto; 5} 6 7/* Object-fit for consistent sizing */ 8.thumbnail { 9 width: 100%; 10 aspect-ratio: 16 / 9; 11 object-fit: cover; 12} 13 14/* Art direction with picture */ 15.hero-image { 16 width: 100%; 17 height: 300px; 18 object-fit: cover; 19} 20 21@media (min-width: 768px) { 22 .hero-image { 23 height: 500px; 24 } 25}
1<!-- HTML picture element --> 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<!-- Responsive with srcset --> 9<img 10 src="image-400.jpg" 11 srcset="image-400.jpg 400w, 12 image-800.jpg 800w, 13 image-1200.jpg 1200w" 14 sizes="(max-width: 600px) 100vw, 15 (max-width: 1200px) 50vw, 16 33vw" 17 alt="Responsive image" 18>

Responsive Tables#

1/* Scrollable table */ 2.table-container { 3 overflow-x: auto; 4} 5 6/* Stacked table on mobile */ 7@media (max-width: 768px) { 8 .responsive-table thead { 9 display: none; 10 } 11 12 .responsive-table tr { 13 display: block; 14 margin-bottom: 1rem; 15 border: 1px solid #ddd; 16 } 17 18 .responsive-table td { 19 display: flex; 20 justify-content: space-between; 21 padding: 0.5rem; 22 border-bottom: 1px solid #eee; 23 } 24 25 .responsive-table td::before { 26 content: attr(data-label); 27 font-weight: bold; 28 } 29}

Breakpoint System#

1/* Tailwind-like breakpoints with CSS */ 2:root { 3 --breakpoint-sm: 640px; 4 --breakpoint-md: 768px; 5 --breakpoint-lg: 1024px; 6 --breakpoint-xl: 1280px; 7 --breakpoint-2xl: 1536px; 8} 9 10/* Using CSS custom media (future) */ 11@custom-media --sm (min-width: 640px); 12@custom-media --md (min-width: 768px); 13@custom-media --lg (min-width: 1024px); 14 15/* For now, use standard media queries */ 16.container { 17 width: 100%; 18 padding: 0 1rem; 19 margin: 0 auto; 20} 21 22@media (min-width: 640px) { 23 .container { max-width: 640px; } 24} 25 26@media (min-width: 768px) { 27 .container { max-width: 768px; } 28} 29 30@media (min-width: 1024px) { 31 .container { max-width: 1024px; } 32} 33 34@media (min-width: 1280px) { 35 .container { max-width: 1280px; } 36}

Best Practices#

Approach: ✓ Start mobile-first ✓ Use relative units (rem, em, %) ✓ Leverage flexbox and grid ✓ Use clamp() for fluid sizing Testing: ✓ Test on real devices ✓ Use browser dev tools ✓ Check touch targets (44px+) ✓ Verify content reflow Performance: ✓ Optimize images ✓ Use responsive images ✓ Minimize layout shifts ✓ Consider container queries

Conclusion#

Modern CSS provides powerful tools for responsive design. Use flexbox for one-dimensional layouts, grid for two-dimensional layouts, and container queries for component-level responsiveness. Fluid typography with clamp() reduces breakpoint management and creates smoother scaling.

Share this article

Help spread the word about Bootspring