The Screen Problem
People visit your website from a dizzying range of devices: 6-inch phones, 10-inch tablets, 13-inch laptops, 27-inch desktops, and everything in between. Foldable phones now have two different screen sizes depending on whether they're folded or not.
Responsive web design is the approach that makes one website work across all of them — no separate mobile site, no pinch-to-zoom, no horizontal scrolling.
This isn't a nice-to-have anymore. Google uses mobile-first indexing, meaning it evaluates the mobile version of your site for ranking. If your site doesn't work well on mobile, it doesn't work well for Google.
Mobile-First vs. Desktop-First
Desktop-First (The Old Way)
Design for large screens, then use CSS media queries to shrink things down for smaller screens.
The problem: You end up removing features and compressing layouts. The mobile experience feels like a cramped version of the "real" site.
Mobile-First (The Right Way)
Start with the smallest screen. Design the core experience first. Then enhance and expand for larger screens.
Why it works better:
- Forces you to prioritise content (what actually matters?)
- Base CSS is simpler and lighter
- Progressive enhancement means mobile loads faster
- Matches how Google evaluates your site
- Most of your traffic is probably mobile anyway
In CSS terms:
/* Mobile-first: base styles are for mobile */
.container {
padding: 1rem;
display: flex;
flex-direction: column;
}
/* Then enhance for larger screens */
@media (min-width: 768px) {
.container {
padding: 2rem;
flex-direction: row;
}
}
@media (min-width: 1024px) {
.container {
max-width: 1200px;
margin: 0 auto;
}
}
Notice: min-width queries, not max-width. You're building up from mobile, not stripping down from desktop.
The CSS Layout Toolkit
Flexbox: One-Dimensional Layouts
Flexbox handles rows OR columns. It's ideal for navigation bars, card rows, form layouts, and aligning items within a container.
.nav {
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
}
.card-row {
display: flex;
gap: 1.5rem;
flex-wrap: wrap;
}
.card {
flex: 1 1 300px; /* Grow, shrink, min-width 300px */
}
When to use Flexbox:
- Navigation bars
- Centering content (vertically and horizontally)
- Distributing space between items
- Simple card grids
- Form layouts
CSS Grid: Two-Dimensional Layouts
Grid handles rows AND columns simultaneously. It's the right tool for page layouts, complex grids, and anything that needs precise placement.
.page-layout {
display: grid;
grid-template-columns: 1fr;
gap: 1.5rem;
}
@media (min-width: 768px) {
.page-layout {
grid-template-columns: 250px 1fr;
}
}
@media (min-width: 1024px) {
.page-layout {
grid-template-columns: 250px 1fr 300px;
}
}
Auto-fit grid (responsive without media queries):
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 1.5rem;
}
This creates a grid that automatically adjusts the number of columns based on available space. No breakpoints needed.
When to use Grid:
- Page layouts (header, sidebar, main, footer)
- Card grids
- Complex magazine-style layouts
- Anything requiring precise row AND column control
Flexbox + Grid Together
They're not competitors — use both:
- Grid for the overall page structure
- Flexbox for alignment within individual components
/* Grid for the page layout */
.page {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 2rem;
}
/* Flexbox for each card's internal layout */
.card {
display: flex;
flex-direction: column;
justify-content: space-between;
}
Breakpoints: Where to Draw the Lines
Breakpoints are the screen widths where your layout changes.
Common Breakpoints in 2026
/* Small phones */
@media (min-width: 480px) { }
/* Large phones / small tablets */
@media (min-width: 640px) { }
/* Tablets */
@media (min-width: 768px) { }
/* Small laptops */
@media (min-width: 1024px) { }
/* Desktops */
@media (min-width: 1280px) { }
/* Large desktops */
@media (min-width: 1536px) { }
The Better Approach: Content-Based Breakpoints
Instead of designing for specific devices, let your content dictate breakpoints.
Process:
- Start with your content on a narrow screen
- Slowly widen the browser
- When the layout starts looking awkward or stretched, add a breakpoint
- Adjust the layout at that width
- Continue widening
This approach is more resilient than targeting specific devices, because new devices with new screen sizes appear constantly.
Container Queries: The New Frontier
Container queries let components respond to their parent container's size instead of the viewport.
.card-container {
container-type: inline-size;
}
@container (min-width: 400px) {
.card {
display: flex;
flex-direction: row;
}
}
Why this matters: A card component can adapt whether it's in a wide main column or a narrow sidebar — without knowing anything about the viewport.
Container queries have excellent browser support in 2026 and are becoming the preferred approach for component-level responsive design.
Fluid Typography
Fixed font sizes (16px everywhere) don't scale well. Fluid typography smoothly adjusts between a minimum and maximum size.
The clamp() Function
h1 {
font-size: clamp(1.75rem, 4vw, 3rem);
}
p {
font-size: clamp(1rem, 1.5vw, 1.125rem);
}
clamp(minimum, preferred, maximum) — the font scales with viewport width but never goes below the minimum or above the maximum.
Benefits:
- No media queries needed for font sizing
- Smooth scaling between breakpoints
- Minimum size ensures readability on mobile
- Maximum size prevents absurdly large text on ultrawide monitors
A Complete Fluid Type Scale
:root {
--text-sm: clamp(0.8rem, 1vw, 0.875rem);
--text-base: clamp(1rem, 1.5vw, 1.125rem);
--text-lg: clamp(1.125rem, 2vw, 1.5rem);
--text-xl: clamp(1.5rem, 3vw, 2rem);
--text-2xl: clamp(1.75rem, 4vw, 3rem);
--text-3xl: clamp(2rem, 5vw, 4rem);
}
Responsive Images
Images are typically the heaviest assets on a page. Serving a 2000px image to a 400px phone screen wastes bandwidth and slows everything down.
The srcset Approach
<img
src="image-800.jpg"
srcset="image-400.jpg 400w,
image-800.jpg 800w,
image-1200.jpg 1200w"
sizes="(max-width: 600px) 100vw,
(max-width: 1200px) 50vw,
33vw"
alt="Descriptive alt text"
loading="lazy"
width="800"
height="600"
>
What this does: The browser picks the most appropriate image size based on screen width and pixel density.
The picture Element
For art direction — showing different crops or images at different sizes:
<picture>
<source media="(min-width: 1024px)" srcset="hero-wide.webp">
<source media="(min-width: 640px)" srcset="hero-medium.webp">
<img src="hero-mobile.webp" alt="Hero image">
</picture>
CSS Techniques
img {
max-width: 100%;
height: auto;
display: block;
}
.hero-image {
width: 100%;
aspect-ratio: 16 / 9;
object-fit: cover;
}
aspect-ratio combined with object-fit: cover ensures images maintain their proportions without distortion at any size. Setting aspect-ratio also reserves space in the layout, preventing layout shift (CLS).
Responsive Navigation
Navigation is one of the trickiest responsive challenges.
The Hamburger Menu
The standard approach: full navigation on desktop, hamburger icon on mobile.
Best practices:
- Use the standard three-line hamburger icon (people know what it means)
- Make the tap target at least 44x44px
- Animate the menu opening smoothly
- Overlay or push-down pattern (don't scroll the user)
- Allow closing by tapping outside the menu
Alternative Patterns
Bottom navigation (mobile apps style):
- Tab bar fixed at the bottom of the screen
- 3-5 key actions
- Thumb-friendly on large phones
Priority+ pattern:
- Show as many nav items as fit
- Overflow items go into a "More" dropdown
- Adapts to any width without a hamburger
Touch Targets and Mobile UX
Mobile isn't just smaller screens — it's a different interaction model.
Minimum Touch Targets
- 44x44 CSS pixels — Apple's Human Interface Guidelines
- 48x48 CSS pixels — Google's Material Design recommendation
- Adequate spacing between targets (at least 8px gap)
Thumb Zones
On a phone held in one hand, the bottom-centre of the screen is the easiest area to reach. The top corners are hardest.
Design implications:
- Put primary actions in easy-reach zones
- Avoid critical buttons in top corners on mobile
- Consider bottom-fixed CTAs for key conversion actions
Forms on Mobile
- Use appropriate input types (
type="email",type="tel",type="number") - Enable autocomplete
- Large, tappable submit buttons
- Inline validation (show errors as they type)
- Minimize required fields
CSS Frameworks and Utility Classes
Tailwind CSS
Tailwind's responsive utilities make mobile-first trivial:
<div class="flex flex-col md:flex-row gap-4 lg:gap-8">
<div class="w-full md:w-1/3">Sidebar</div>
<div class="w-full md:w-2/3">Main content</div>
</div>
Unprefixed classes are mobile. md: is tablet. lg: is desktop. Simple.
Bootstrap
Bootstrap's grid system is still widely used:
<div class="row">
<div class="col-12 col-md-4">Sidebar</div>
<div class="col-12 col-md-8">Main content</div>
</div>
When to Use a Framework
- Use one when speed matters more than customisation
- Skip it when you need a unique design that doesn't fit into grid patterns
- Tailwind is the current go-to for most modern projects
Testing Responsive Design
Browser DevTools
Every modern browser has responsive testing built in:
- Chrome: DevTools > Toggle device toolbar (Ctrl+Shift+M)
- Safari: Develop > Enter Responsive Design Mode
- Firefox: DevTools > Responsive Design Mode
Limitations: Emulation isn't perfect. Always test on real devices too.
Real Device Testing
Test on at least:
- An iPhone (Safari rendering)
- An Android phone (Chrome rendering)
- A tablet (iPad or Android)
- A budget phone (slower processor, smaller screen)
Why real devices matter:
- Touch interactions feel different
- Performance varies dramatically
- Browsers render slightly differently
- Screen size simulators miss real-world issues
Automated Testing
- Lighthouse — Performance and accessibility audits
- BrowserStack — Test on hundreds of real devices in the cloud
- Percy — Visual regression testing
Performance Considerations
Responsive design isn't just about layout — it's about loading the right assets for each device.
- Responsive images — don't send desktop images to mobile
- Code splitting — load only what's needed for the current viewport
- Lazy loading — defer off-screen content
- Reduce JavaScript — mobile devices have less processing power
- Test on slow connections — Chrome DevTools can simulate 3G
Common Responsive Design Mistakes
- Fixed-width containers — use
max-widthand percentage widths instead - Hover-dependent interactions — touch screens don't hover
- Tiny tap targets — links and buttons too small to tap accurately
- Horizontal scrolling — almost always a bug, not a feature
- Unreadable text — font sizes below 14px on mobile
- Desktop-only testing — launch looking broken on half your traffic
- Ignoring landscape mode — phones rotate too
- Heavy animations on mobile — drain battery and slow performance
- Fixed-position elements covering content — especially sticky headers on small screens
- Not testing forms on mobile — keyboard, autocomplete, and validation all behave differently
Responsive Design Checklist
- [ ] Mobile-first CSS (base styles for mobile,
min-widthmedia queries) - [ ] All content readable without horizontal scrolling
- [ ] Touch targets minimum 44x44px
- [ ] Responsive images with srcset or picture element
- [ ] Fluid typography with clamp()
- [ ] Navigation works on all screen sizes
- [ ] Forms optimised for mobile input
- [ ] No hover-only interactions
- [ ] Tested on real mobile and tablet devices
- [ ] Performance acceptable on 3G connections
- [ ] Core Web Vitals passing on mobile
- [ ] Viewport meta tag present:
<meta name="viewport" content="width=device-width, initial-scale=1">
Responsive design isn't a feature you bolt on at the end. It's a mindset that shapes every decision from the first line of CSS. Start mobile, build up, test constantly.