| name | responsive-design |
| description | Mobile-first responsive design - breakpoints, flexible layouts, media queries, responsive images, and cross-device testing. Build interfaces that work everywhere. |
| tags | ["responsive","mobile-first","css","breakpoints","media-queries","flexbox","grid"] |
| version | 1.0.0 |
| author | Enhanced from responsive design best practices) |
Responsive Design
Overview
Build interfaces that adapt seamlessly to any screen size.
Why responsive design matters:
- Mobile traffic: 60%+ of web traffic is mobile
- SEO: Google prioritizes mobile-friendly sites
- User experience: Users expect sites to work on their device
- Cost: One codebase for all devices
- Future-proof: Works on devices that don't exist yet
Key principles:
- Mobile-first: Design for small screens first
- Flexible layouts: Use relative units (%, em, rem)
- Breakpoints: Adapt at specific screen sizes
- Touch-friendly: Large tap targets (44×44px)
- Performance: Fast on slow mobile networks
When to Use
Use for:
- All web applications
- All websites
- Mobile apps (responsive web views)
- Email templates
- Any user-facing interface
Critical for:
- E-commerce (mobile conversion)
- Content sites (mobile readership)
- SaaS applications (mobile access)
- Marketing sites (mobile traffic)
The 5-Layer Responsive Framework
┌─────────────────────────────────────────────────────────┐
│ RESPONSIVE DESIGN FRAMEWORK │
└─────────────────────────────────────────────────────────┘
┌──────────────┐
│ LAYER 1 │ Mobile-First Strategy
│ MOBILE-FIRST │ - Start with mobile
│ │ - Progressive enhancement
└──────┬───────┘ - Content priority
│
▼
┌──────────────┐
│ LAYER 2 │ Flexible Layouts
│ LAYOUTS │ - Flexbox
│ │ - CSS Grid
└──────┬───────┘ - Relative units
│
▼
┌──────────────┐
│ LAYER 3 │ Breakpoints
│ BREAKPOINTS │ - Media queries
│ │ - Device ranges
└──────┬───────┘ - Content-based
│
▼
┌──────────────┐
│ LAYER 4 │ Responsive Images
│ IMAGES │ - srcset
│ │ - picture element
└──────┬───────┘ - Lazy loading
│
▼
┌──────────────┐
│ LAYER 5 │ Testing
│ TESTING │ - Device testing
│ │ - Browser testing
└──────────────┘ - Performance
Layer 1: Mobile-First Strategy
Goal: Design for mobile first, enhance for desktop
Mobile-First Approach:
.container {
width: 100%;
padding: 16px;
}
.card {
margin-bottom: 16px;
}
@media (min-width: 768px) {
.container {
padding: 24px;
}
.card {
width: 48%;
display: inline-block;
}
}
@media (min-width: 1024px) {
.container {
max-width: 1200px;
margin: 0 auto;
padding: 32px;
}
.card {
width: 32%;
}
}
Desktop-First (❌ Don't do this):
.container {
max-width: 1200px;
margin: 0 auto;
padding: 32px;
}
@media (max-width: 1024px) {
.container {
padding: 24px;
}
}
@media (max-width: 768px) {
.container {
padding: 16px;
}
}
Why Mobile-First?
## Benefits
1. **Performance:** Mobile gets minimal CSS, desktop gets enhancements
2. **Progressive enhancement:** Works on all devices
3. **Content priority:** Forces focus on essential content
4. **Future-proof:** New devices get mobile styles by default
5. **Easier to maintain:** Add features, don't remove them
## Content Priority
**Mobile forces you to prioritize:**
- What's most important?
- What can be hidden/collapsed?
- What's the core user journey?
**Example:**
```html
<!-- Mobile: Essential content only -->
<header>
<h1>Logo</h1>
<button>Menu</button>
</header>
<!-- Desktop: Full navigation -->
<header>
<h1>Logo</h1>
<nav>
<a href="/">Home</a>
<a href="/about">About</a>
<a href="/products">Products</a>
<a href="/contact">Contact</a>
</nav>
<button>Search</button>
<button>Cart</button>
</header>
---
## Layer 2: Flexible Layouts
### Goal: Layouts that adapt to any screen size
**Flexbox:**
```css
/* Flexible container */
.container {
display: flex;
flex-wrap: wrap;
gap: 16px;
}
/* Flexible items */
.item {
flex: 1 1 300px; /* grow, shrink, basis */
min-width: 0; /* Prevent overflow */
}
/* Common patterns */
/* Center content */
.center {
display: flex;
justify-content: center;
align-items: center;
}
/* Space between */
.space-between {
display: flex;
justify-content: space-between;
align-items: center;
}
/* Column on mobile, row on desktop */
.responsive-flex {
display: flex;
flex-direction: column;
}
@media (min-width: 768px) {
.responsive-flex {
flex-direction: row;
}
}
CSS Grid:
.grid {
display: grid;
gap: 16px;
grid-template-columns: 1fr;
}
@media (min-width: 768px) {
.grid {
grid-template-columns: repeat(2, 1fr);
}
}
@media (min-width: 1024px) {
.grid {
grid-template-columns: repeat(3, 1fr);
}
}
.auto-grid {
display: grid;
gap: 16px;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
}
.sidebar-layout {
display: grid;
gap: 24px;
grid-template-columns: 1fr;
}
@media (min-width: 1024px) {
.sidebar-layout {
grid-template-columns: 250px 1fr;
}
}
.holy-grail {
display: grid;
min-height: 100vh;
grid-template-rows: auto 1fr auto;
grid-template-columns: 1fr;
}
@media (min-width: 1024px) {
.holy-grail {
grid-template-columns: 200px 1fr 200px;
}
.header {
grid-column: 1 / -1;
}
.footer {
grid-column: 1 / -1;
}
}
Relative Units:
.container {
width: 1200px;
padding: 20px;
font-size: 16px;
}
.container {
max-width: 75rem;
padding: 1.25rem;
font-size: 1rem;
}
.column {
width: 50%;
}
.spacing {
margin-bottom: 1.5rem;
padding: 1rem 2rem;
}
.button {
font-size: 1rem;
padding: 0.5em 1em;
}
.hero {
height: 100vh;
width: 100vw;
}
.heading {
font-size: clamp(1.5rem, 5vw, 3rem);
}
Layer 3: Breakpoints
Goal: Adapt layout at specific screen sizes
Standard Breakpoints:
@media (min-width: 576px) {
}
@media (min-width: 768px) {
}
@media (min-width: 1024px) {
}
@media (min-width: 1280px) {
}
@media (min-width: 1536px) {
}
Content-Based Breakpoints:
.card-grid {
display: grid;
gap: 16px;
grid-template-columns: 1fr;
}
@media (min-width: 500px) {
.card-grid {
grid-template-columns: repeat(2, 1fr);
}
}
@media (min-width: 900px) {
.card-grid {
grid-template-columns: repeat(3, 1fr);
}
}
Breakpoint Ranges:
@media (min-width: 768px) and (max-width: 1023px) {
.tablet-only {
display: block;
}
}
@media (max-width: 767px) {
.mobile-only {
display: block;
}
}
@media (min-width: 1024px) {
.desktop-only {
display: block;
}
}
Orientation:
@media (orientation: portrait) {
.container {
flex-direction: column;
}
}
@media (orientation: landscape) {
.container {
flex-direction: row;
}
}
Print:
@media print {
nav, aside, .no-print {
display: none;
}
body {
font-size: 12pt;
color: black;
background: white;
}
h1, h2, h3 {
page-break-after: avoid;
}
a[href]:after {
content: " (" attr(href) ")";
}
}
Layer 4: Responsive Images
Goal: Serve appropriate images for each device
srcset (Resolution Switching):
<img
src="image-800w.jpg"
srcset="
image-400w.jpg 400w,
image-800w.jpg 800w,
image-1200w.jpg 1200w,
image-1600w.jpg 1600w
"
sizes="
(max-width: 600px) 100vw,
(max-width: 1200px) 50vw,
33vw
"
alt="Responsive image"
/>
picture Element (Art Direction):
<picture>
<source
media="(max-width: 767px)"
srcset="image-square-400w.jpg 400w, image-square-800w.jpg 800w"
/>
<source
media="(max-width: 1023px)"
srcset="image-wide-800w.jpg 800w, image-wide-1600w.jpg 1600w"
/>
<source
srcset="image-original-1200w.jpg 1200w, image-original-2400w.jpg 2400w"
/>
<img src="image-original-1200w.jpg" alt="Responsive image" />
</picture>
WebP with Fallback:
<picture>
<source type="image/webp" srcset="image.webp" />
<img src="image.jpg" alt="Image" />
</picture>
Lazy Loading:
<img src="image.jpg" alt="Image" loading="lazy" />
<img
src="placeholder.jpg"
data-src="actual-image.jpg"
alt="Image"
loading="lazy"
/>
Background Images:
.hero {
background-image: url('hero-mobile.jpg');
background-size: cover;
background-position: center;
}
@media (min-width: 768px) {
.hero {
background-image: url('hero-tablet.jpg');
}
}
@media (min-width: 1024px) {
.hero {
background-image: url('hero-desktop.jpg');
}
}
@media (min-width: 1024px) and (-webkit-min-device-pixel-ratio: 2) {
.hero {
background-image: url('hero-desktop@2x.jpg');
}
}
Layer 5: Testing
Goal: Verify responsive design works everywhere
Browser DevTools:
Real Device Testing:
## Test on Real Devices
**iOS:**
- iPhone SE (small screen)
- iPhone 14 (standard)
- iPhone 14 Pro Max (large)
- iPad (tablet)
**Android:**
- Samsung Galaxy S23 (standard)
- Google Pixel 7 (standard)
- Samsung Galaxy Tab (tablet)
**Desktop:**
- Windows (Chrome, Edge, Firefox)
- Mac (Safari, Chrome, Firefox)
- Linux (Chrome, Firefox)
## Testing Tools
**BrowserStack:** Test on real devices in the cloud
**LambdaTest:** Cross-browser testing
**Sauce Labs:** Automated testing
**Responsively App:** Desktop app for responsive testing
Responsive Testing Checklist:
## Visual Testing
- [ ] Layout doesn't break at any size
- [ ] No horizontal scrolling (except intentional)
- [ ] Images scale properly
- [ ] Text is readable (not too small)
- [ ] Touch targets are 44×44px minimum
- [ ] Navigation works on mobile
- [ ] Forms are usable on mobile
- [ ] Modals/popups work on mobile
## Functional Testing
- [ ] All features work on mobile
- [ ] Touch gestures work (swipe, pinch, tap)
- [ ] Keyboard works on tablets
- [ ] Orientation change works (portrait ↔ landscape)
- [ ] Zoom works (pinch-to-zoom)
- [ ] Performance is acceptable on mobile
## Content Testing
- [ ] All content visible on mobile
- [ ] No content hidden unintentionally
- [ ] Images have appropriate alt text
- [ ] Videos play on mobile
- [ ] Forms are accessible
## Performance Testing
- [ ] Page loads in <3s on 3G
- [ ] Images optimized (WebP, lazy loading)
- [ ] CSS/JS minified
- [ ] No render-blocking resources
- [ ] Core Web Vitals pass (LCP, FID, CLS)
Common Responsive Patterns
Navigation:
<nav class="mobile-nav">
<button class="menu-toggle" aria-label="Toggle menu">
☰
</button>
<ul class="menu" hidden>
<li><a href="/">Home</a></li>
<li><a href="/about">About</a></li>
<li><a href="/products">Products</a></li>
<li><a href="/contact">Contact</a></li>
</ul>
</nav>
<style>
.menu {
display: none;
}
.menu[hidden="false"] {
display: block;
position: fixed;
top: 60px;
left: 0;
right: 0;
background: white;
padding: 16px;
}
@media (min-width: 768px) {
.menu-toggle {
display: none;
}
.menu {
display: flex !important;
position: static;
gap: 24px;
}
}
</style>
<script>
document.querySelector('.menu-toggle').addEventListener('click', () => {
const menu = document.querySelector('.menu');
const isHidden = menu.getAttribute('hidden') === 'true';
menu.setAttribute('hidden', !isHidden);
});
</script>
Cards:
.card-grid {
display: grid;
gap: 16px;
grid-template-columns: 1fr;
}
@media (min-width: 768px) {
.card-grid {
grid-template-columns: repeat(2, 1fr);
}
}
@media (min-width: 1024px) {
.card-grid {
grid-template-columns: repeat(3, 1fr);
}
}
.card-grid-auto {
display: grid;
gap: 16px;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
}
Typography:
body {
font-size: clamp(1rem, 2.5vw, 1.125rem);
line-height: 1.6;
}
h1 {
font-size: clamp(2rem, 5vw + 1rem, 4rem);
line-height: 1.2;
}
h2 {
font-size: clamp(1.5rem, 4vw + 0.5rem, 3rem);
}
h3 {
font-size: clamp(1.25rem, 3vw + 0.25rem, 2rem);
}
h1 {
font-size: 2rem;
}
@media (min-width: 768px) {
h1 {
font-size: 3rem;
}
}
@media (min-width: 1024px) {
h1 {
font-size: 4rem;
}
}
Tables:
.table-container {
overflow-x: auto;
-webkit-overflow-scrolling: touch;
}
table {
width: 100%;
min-width: 600px;
}
@media (max-width: 767px) {
table, thead, tbody, th, td, tr {
display: block;
}
thead tr {
position: absolute;
top: -9999px;
left: -9999px;
}
tr {
margin-bottom: 16px;
border: 1px solid #ddd;
}
td {
border: none;
position: relative;
padding-left: 50%;
}
td:before {
content: attr(data-label);
position: absolute;
left: 6px;
font-weight: bold;
}
}
Responsive Design Checklist
Mobile-First:
Flexible Layouts:
Breakpoints:
Images:
Touch:
Testing:
Common Responsive Mistakes
Mistake 1: Desktop-First
Problem: Mobile gets bloated CSS
Solution: Start with mobile, enhance for desktop
Mistake 2: Fixed Widths
Problem: Layout breaks on small screens
Solution: Use max-width, percentages, or flexible units
Mistake 3: Ignoring Touch
Problem: Tiny tap targets, hover-only interactions
Solution: 44×44px targets, no hover-only features
Mistake 4: Not Testing on Real Devices
Problem: Looks good in DevTools, broken on real phones
Solution: Test on actual devices
Mistake 5: Disabling Zoom
Problem: Accessibility issue
Solution: Allow pinch-to-zoom
Mistake 6: Too Many Breakpoints
Problem: Hard to maintain
Solution: Use content-based breakpoints, auto-fit grids
Integration with Other Skills
Use before responsive design:
accessibility-audit - Accessible responsive design
performance-optimization - Fast mobile experience
Use during responsive design:
component-library - Responsive components
web-performance - Optimize for mobile
Use after responsive design:
user-research - Test with real users
requesting-code-review - Review responsive changes
Remember: Responsive design is not optional. 60%+ of traffic is mobile. Design for mobile first, enhance for desktop. Test on real devices. Performance matters more on mobile. Touch targets must be 44×44px minimum.