Responsive Design
Introduction
Responsive web design ensures your websites look and function well across all devices and screen sizes. This tutorial covers essential techniques for creating fluid, adaptable layouts.
What you'll learn
- Viewport configuration and responsive units
- Media queries and breakpoints
- Flexible layouts with Flexbox and Grid
- Responsive images and typography
- Mobile-first development approach
Viewport & Units
The viewport meta tag and responsive units are fundamental to responsive design:
<!-- Viewport Meta Tag -->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
Responsive units help create flexible layouts:
/* Responsive Units */
.container {
width: 90%; /* Percentage */
max-width: 1200px; /* Fixed maximum */
margin: 0 auto;
}
.hero {
height: 100vh; /* Viewport height */
padding: 2rem; /* Root em */
font-size: 1.2em; /* Em relative to parent */
}
.card {
width: clamp(300px, 50%, 600px); /* Minimum, preferred, maximum */
}
Note: Use relative units like %, vh/vw, rem/em for better scalability across different screen sizes.
Media Queries
Media queries allow you to apply different styles based on device characteristics:
/* Mobile First Approach */
.container {
padding: 1rem;
}
/* Tablet and up */
@media (min-width: 768px) {
.container {
padding: 2rem;
}
}
/* Desktop */
@media (min-width: 1024px) {
.container {
padding: 3rem;
}
}
/* Print styles */
@media print {
.no-print {
display: none;
}
}
Flexbox Layout
Flexbox provides a powerful way to create flexible layouts:
/* Responsive Navigation */
.nav {
display: flex;
flex-direction: column;
}
@media (min-width: 768px) {
.nav {
flex-direction: row;
justify-content: space-between;
align-items: center;
}
}
/* Flexible Card Grid */
.card-container {
display: flex;
flex-wrap: wrap;
gap: 1rem;
}
.card {
flex: 1 1 300px; /* grow shrink basis */
max-width: 100%;
}
CSS Grid
CSS Grid is perfect for complex, two-dimensional layouts:
/* Responsive Grid Layout */
.grid {
display: grid;
gap: 1rem;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
}
/* Complex Layout */
.page-layout {
display: grid;
grid-template-areas:
"header"
"nav"
"main"
"sidebar"
"footer";
}
@media (min-width: 768px) {
.page-layout {
grid-template-areas:
"header header"
"nav nav"
"sidebar main"
"footer footer";
grid-template-columns: 250px 1fr;
}
}
Responsive Images
Make images responsive and optimize them for different devices:
<!-- Basic Responsive Image -->
<img src="image.jpg" alt="Description" class="responsive-img">
<!-- Art Direction with Picture Element -->
<picture>
<source media="(min-width: 800px)" srcset="hero-large.jpg">
<source media="(min-width: 400px)" srcset="hero-medium.jpg">
<img src="hero-small.jpg" alt="Hero image">
</picture>
<!-- Responsive Background Images -->
<div class="hero-banner"></div>
/* Responsive Image Styles */
.responsive-img {
max-width: 100%;
height: auto;
}
.hero-banner {
background-image: url('small.jpg');
background-size: cover;
background-position: center;
}
@media (min-width: 768px) {
.hero-banner {
background-image: url('large.jpg');
}
}
Typography
Implement responsive typography for better readability:
/* Fluid Typography */
:root {
font-size: 16px;
}
@media (min-width: 768px) {
:root {
font-size: calc(16px + 0.5vw);
}
}
/* Responsive Headings */
h1 {
font-size: clamp(2rem, 5vw, 4rem);
line-height: 1.2;
}
/* Article Text */
.article {
font-size: clamp(1rem, 2vw, 1.2rem);
line-height: 1.6;
max-width: 70ch; /* Optimal line length */
}
Practice Project
Let's create a responsive card component:
<div class="card-grid">
<article class="card">
<img src="image.jpg" alt="Card image" class="card-img">
<div class="card-content">
<h2 class="card-title">Card Title</h2>
<p class="card-text">Card description goes here...</p>
<a href="#" class="card-button">Learn More</a>
</div>
</article>
<!-- More cards... -->
</div>
/* Responsive Card Grid */
.card-grid {
display: grid;
gap: 1.5rem;
padding: 1rem;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
}
.card {
background: white;
border-radius: 8px;
overflow: hidden;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
transition: transform 0.3s ease;
}
.card:hover {
transform: translateY(-5px);
}
.card-img {
width: 100%;
height: 200px;
object-fit: cover;
}
.card-content {
padding: 1.5rem;
}
.card-title {
font-size: clamp(1.25rem, 3vw, 1.5rem);
margin-bottom: 0.5rem;
}
.card-text {
font-size: clamp(0.875rem, 2vw, 1rem);
color: #666;
margin-bottom: 1.5rem;
}
.card-button {
display: inline-block;
padding: 0.75rem 1.5rem;
background: var(--primary-color);
color: white;
text-decoration: none;
border-radius: 4px;
transition: background 0.3s ease;
}
.card-button:hover {
background: var(--primary-dark);
}
@media (max-width: 768px) {
.card-grid {
gap: 1rem;
padding: 0.5rem;
}
.card-content {
padding: 1rem;
}
}