Responsive Design
Responsive Design Techniques & Patterns
Master responsive web design patterns. Learn flexible grids, responsive typography, container queries, and modern CSS techniques for building websites that adapt to any device.
Responsive Design Principles
Responsive web design is an approach that makes web pages render well on all devices and screen sizes by using flexible layouts, images, and CSS media queries.
🔄 Fluid Grids
Use relative units (%, fr) instead of fixed pixels
ðŸ–¼ï¸ Flexible Images
Images scale within containing elements
📱 Media Queries
Apply styles based on device characteristics
📠Breakpoints
Design for common device sizes
Common Breakpoints
CSS
/* Mobile first approach */
/* Extra small devices (phones, less than 576px) */
/* No media query - this is the default */
/* Small devices (landscape phones, 576px and up) */
@media (min-width: 576px) {"{ }"}
/* Medium devices (tablets, 768px and up) */
@media (min-width: 768px) {"{ }"}
/* Large devices (desktops, 992px and up) */
@media (min-width: 992px) {"{ }"}
/* Extra large devices (large desktops, 1200px and up) */
@media (min-width: 1200px) {"{ }"}
/* 2K screens */
@media (min-width: 1920px) {"{ }"}Flexible Grid with Flexbox
HTML
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
.container {
display: flex;
flex-wrap: wrap;
gap: 20px;
padding: 20px;
}
.column {
flex: 1 1 300px; /* grow, shrink, basis */
background: #4CAF50;
padding: 20px;
color: white;
}
/* Automatically wraps to new lines when space runs out */
</style>
</head>
<body>
<div class="container">
<div class="column">Column 1</div>
<div class="column">Column 2</div>
<div class="column">Column 3</div>
</div>
</body>
</html>CSS Grid for Responsive Layouts
HTML
<style>
.grid-container {
display: grid;
/* Auto-fit: creates as many columns as fit */
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 20px;
padding: 20px;
}
.grid-item {
background: #2196F3;
padding: 20px;
color: white;
}
/* Result: Automatically responsive!
- 1 column on mobile (< 300px width)
- 2 columns on tablet
- 3+ columns on desktop
- No media queries needed! */
</style>
<div class="grid-container">
<div class="grid-item">Item 1</div>
<div class="grid-item">Item 2</div>
<div class="grid-item">Item 3</div>
<div class="grid-item">Item 4</div>
<div class="grid-item">Item 5</div>
<div class="grid-item">Item 6</div>
</div>Responsive Typography
Fluid Typography with clamp()
CSS
<style>
/* clamp(minimum, preferred, maximum) */
h1 {
font-size: clamp(1.5rem, 5vw, 3rem);
/* Min: 24px, scales with viewport, Max: 48px */
}
h2 {
font-size: clamp(1.25rem, 3vw, 2rem);
}
p {
font-size: clamp(1rem, 2vw, 1.125rem);
}
/* Responsive line height */
.content {
line-height: clamp(1.4, 1.5vw, 1.8);
}
</style>Viewport Units
CSS
<style>
/* vw = viewport width percentage */
h1 {
font-size: 5vw; /* 5% of viewport width */
}
/* Combine with calc() for better control */
h1 {
font-size: calc(16px + 2vw);
/* Base 16px + 2% of viewport width */
}
/* Use with min/max for constraints */
h1 {
font-size: max(24px, min(5vw, 48px));
}
</style>Responsive Images
Simple Responsive Images
HTML
<style>
img {
max-width: 100%;
height: auto;
display: block;
}
</style>
<img src="photo.jpg" alt="Description">Art Direction with Picture Element
HTML
<picture>
<!-- Desktop: landscape image -->
<source media="(min-width: 1024px)" srcset="desktop-wide.jpg">
<!-- Tablet: medium image -->
<source media="(min-width: 768px)" srcset="tablet-medium.jpg">
<!-- Mobile: portrait image -->
<img src="mobile-portrait.jpg" alt="Responsive image">
</picture>Resolution Switching with srcset
HTML
<img src="image-400.jpg"
srcset="image-400.jpg 400w,
image-800.jpg 800w,
image-1200.jpg 1200w"
sizes="(max-width: 600px) 100vw,
(max-width: 900px) 50vw,
33vw"
alt="Responsive image">
<!-- Browser automatically picks best image based on:
- Device screen size
- Device pixel ratio
- sizes attribute hints -->Container Queries (Modern)
Container queries allow elements to respond to their container's size, not just viewport size:
HTML
<style>
/* Define container */
.card-container {
container-type: inline-size;
container-name: card;
}
.card {
padding: 20px;
}
/* Query based on container width, not viewport */
@container card (min-width: 400px) {
.card {
display: grid;
grid-template-columns: 1fr 2fr;
}
}
@container card (min-width: 600px) {
.card h2 {
font-size: 2rem;
}
}
</style>
<!-- Card adapts to container size -->
<div class="card-container">
<div class="card">
<img src="photo.jpg" alt="Photo">
<div>
<h2>Title</h2>
<p>Content...</p>
</div>
</div>
</div>Responsive Navigation Patterns
Hamburger Menu (Mobile)
HTML
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
nav {
background: #333;
color: white;
}
.menu-toggle {
display: none;
background: none;
border: none;
color: white;
font-size: 24px;
padding: 15px;
cursor: pointer;
}
.nav-links {
list-style: none;
display: flex;
gap: 20px;
padding: 0;
margin: 0;
}
.nav-links a {
color: white;
text-decoration: none;
padding: 15px 20px;
display: block;
}
/* Mobile styles */
@media (max-width: 768px) {
.menu-toggle {
display: block;
}
.nav-links {
display: none;
flex-direction: column;
position: absolute;
top: 60px;
left: 0;
right: 0;
background: #333;
}
.nav-links.active {
display: flex;
}
}
</style>
</head>
<body>
<nav>
<button class="menu-toggle" onclick="toggleMenu()">☰</button>
<ul class="nav-links" id="navLinks">
<li><a href="#home">Home</a></li>
<li><a href="#about">About</a></li>
<li><a href="#services">Services</a></li>
<li><a href="#contact">Contact</a></li>
</ul>
</nav>
<script>
function toggleMenu() {
document.getElementById('navLinks').classList.toggle('active');
}
</script>
</body>
</html>Responsive Tables
Horizontal Scroll (Simple)
HTML
<style>
.table-wrapper {
overflow-x: auto;
-webkit-overflow-scrolling: touch; /* Smooth scrolling on iOS */
}
table {
min-width: 600px; /* Prevent squishing */
width: 100%;
}
</style>
<div class="table-wrapper">
<table>
<thead>
<tr>
<th>Name</th>
<th>Email</th>
<th>Phone</th>
<th>Address</th>
</tr>
</thead>
<tbody>
<tr>
<td>John Doe</td>
<td>john@example.com</td>
<td>555-1234</td>
<td>123 Main St</td>
</tr>
</tbody>
</table>
</div>Stacked Layout (Mobile)
HTML
<style>
table {
width: 100%;
}
@media (max-width: 768px) {
/* Hide thead */
thead {
display: none;
}
/* Stack rows */
tr {
display: block;
margin-bottom: 20px;
border: 1px solid #ddd;
}
/* Display cells as blocks with labels */
td {
display: block;
text-align: right;
padding: 10px;
border-bottom: 1px solid #ddd;
}
td::before {
content: attr(data-label);
float: left;
font-weight: bold;
}
}
</style>
<table>
<thead>
<tr>
<th>Name</th>
<th>Email</th>
<th>Phone</th>
</tr>
</thead>
<tbody>
<tr>
<td data-label="Name">John Doe</td>
<td data-label="Email">john@example.com</td>
<td data-label="Phone">555-1234</td>
</tr>
</tbody>
</table>Testing Responsive Design
Browser DevTools
- Chrome: F12 → Toggle Device Toolbar (Ctrl+Shift+M)
- Firefox: F12 → Responsive Design Mode (Ctrl+Shift+M)
- Safari: Develop → Enter Responsive Design Mode
Testing Checklist
- ☑ Test all breakpoints (320px, 375px, 768px, 1024px, 1920px)
- ☑ Test landscape and portrait orientations
- ☑ Test with different pixel ratios (1x, 2x, 3x)
- ☑ Test touch interactions on real devices
- ☑ Test with different font sizes
- ☑ Test with slow network (throttling)
- ☑ Test accessibility (screen readers, keyboard navigation)
Performance Optimization
HTML
<!-- Load appropriate images -->
<picture>
<source media="(min-width: 1024px)" srcset="large.jpg">
<source media="(min-width: 768px)" srcset="medium.jpg">
<img src="small.jpg" loading="lazy" alt="Image">
</picture>
<!-- Lazy load images -->
<img src="image.jpg" loading="lazy" alt="Description">
<!-- Preload critical resources -->
<link rel="preload" href="critical.css" as="style">
<link rel="preload" href="hero-image.jpg" as="image">
<!-- Use modern image formats -->
<picture>
<source type="image/webp" srcset="image.webp">
<source type="image/jpeg" srcset="image.jpg">
<img src="image.jpg" alt="Image">
</picture>Best Practices
✅ Do
- Use mobile-first approach
- Test on real devices
- Use relative units (%, rem, em)
- Optimize images for each breakpoint
- Keep touch targets 48x48px minimum
- Use semantic HTML
- Progressive enhancement
⌠Don't
- Use fixed pixel widths
- Hide content on mobile unnecessarily
- Use tiny text (< 16px)
- Forget to test touch interactions
- Load desktop images on mobile
- Disable zoom