CSS Responsive Web Design
Responsive web design is an approach that makes websites work well on all devices and screen sizes. This tutorial covers the essential techniques for creating responsive layouts with CSS.
What is Responsive Design?
Responsive design ensures your website adapts to different screen sizes, from mobile phones to desktop computers. It provides an optimal viewing experience without requiring multiple versions of your site.
Core Concepts
1. Viewport Meta Tag
The viewport meta tag tells browsers how to control the page’s dimensions and scaling:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Responsive Design</title>
</head>
<body>
<!-- Your content here -->
</body>
</html>The viewport meta tag ensures:
width=device-width: Sets the width of the page to follow the screen-width of the deviceinitial-scale=1.0: Sets the initial zoom level when the page is first loaded
Fluid Layouts
1. Relative Units
Use relative units instead of fixed pixels for flexible layouts:
.container {
/* Fixed units (avoid for responsive design) */
width: 960px;
/* Relative units (better for responsive design) */
width: 90%; /* Percentage of parent */
width: 60em; /* Based on font size */
width: 50vw; /* 50% of viewport width */
width: 80vh; /* 80% of viewport height */
width: 100vmin; /* Smaller of viewport width/height */
width: 100vmax; /* Larger of viewport width/height */
}
.text {
font-size: 16px; /* Fixed size */
font-size: 1rem; /* Relative to root font size */
font-size: 1.2em; /* Relative to parent font size */
}2. Flexible Grid System
Create a flexible grid that adapts to container width:
.grid {
display: grid;
gap: 20px;
/* Create flexible columns */
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
}
/* Traditional float-based approach */
.row {
overflow: hidden;
}
.column {
float: left;
width: 33.333%;
padding: 0 15px;
box-sizing: border-box;
}
/* Clearfix for floats */
.row::after {
content: "";
display: table;
clear: both;
}Media Queries
Media queries allow you to apply different CSS rules based on device characteristics.
1. Basic Media Query Syntax
/* Apply styles when viewport width is 768px or less */
@media (max-width: 768px) {
.container {
width: 100%;
padding: 10px;
}
.column {
width: 100%;
margin-bottom: 20px;
}
}
/* Apply styles when viewport width is between 768px and 1024px */
@media (min-width: 768px) and (max-width: 1024px) {
.container {
width: 90%;
max-width: 960px;
}
}
/* Apply styles when viewport width is 1025px or more */
@media (min-width: 1025px) {
.container {
width: 80%;
max-width: 1200px;
}
}2. Common Breakpoints
Use these standard breakpoints for different device sizes:
/* Mobile devices */
@media (max-width: 480px) {
.navigation {
display: none;
}
.mobile-menu {
display: block;
}
}
/* Tablets and small laptops */
@media (min-width: 481px) and (max-width: 768px) {
.container {
padding: 20px;
}
.grid {
grid-template-columns: repeat(2, 1fr);
}
}
/* Laptops and small desktops */
@media (min-width: 769px) and (max-width: 1024px) {
.grid {
grid-template-columns: repeat(3, 1fr);
}
}
/* Large desktops */
@media (min-width: 1025px) {
.container {
max-width: 1200px;
margin: 0 auto;
}
.grid {
grid-template-columns: repeat(4, 1fr);
}
}3. Mobile-First Approach
Start with mobile styles, then add complexity for larger screens:
/* Base styles (mobile-first) */
.container {
width: 100%;
padding: 15px;
}
.navigation {
display: flex;
flex-direction: column;
}
.menu-item {
padding: 10px;
border-bottom: 1px solid #ddd;
}
/* Tablet styles */
@media (min-width: 768px) {
.container {
max-width: 750px;
margin: 0 auto;
}
.navigation {
flex-direction: row;
justify-content: space-between;
}
.menu-item {
border-bottom: none;
border-right: 1px solid #ddd;
}
}
/* Desktop styles */
@media (min-width: 1024px) {
.container {
max-width: 1200px;
}
.menu-item {
padding: 15px 20px;
}
}Flexible Images and Media
1. Responsive Images
Make images scale with their containers:
/* Basic responsive image */
img {
max-width: 100%;
height: auto;
}
/* Responsive image with container */
.image-container {
position: relative;
width: 100%;
padding-bottom: 56.25%; /* 16:9 aspect ratio */
}
.image-container img {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: cover;
}2. Responsive Video
.video-container {
position: relative;
padding-bottom: 56.25%; /* 16:9 aspect ratio */
height: 0;
overflow: hidden;
}
.video-container iframe,
.video-container object,
.video-container embed {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}Modern Responsive Techniques
1. CSS Grid and Flexbox
Use modern layout systems for better responsiveness:
/* Responsive Grid Layout */
.grid-container {
display: grid;
gap: 20px;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
}
/* Responsive Flexbox Layout */
.flex-container {
display: flex;
flex-wrap: wrap;
gap: 15px;
}
.flex-item {
flex: 1 1 300px; /* grow, shrink, basis */
min-width: 300px;
}
/* Responsive Navigation */
.nav {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.nav-item {
flex: 1 1 120px;
text-align: center;
}
@media (max-width: 768px) {
.nav {
flex-direction: column;
}
.nav-item {
flex: none;
}
}2. CSS Custom Properties with Media Queries
Use CSS variables for easier responsive design:
:root {
--container-padding: 15px;
--font-size-base: 16px;
--gap-size: 20px;
--columns: 1;
}
@media (min-width: 768px) {
:root {
--container-padding: 25px;
--font-size-base: 18px;
--gap-size: 30px;
--columns: 2;
}
}
@media (min-width: 1024px) {
:root {
--container-padding: 35px;
--font-size-base: 20px;
--gap-size: 40px;
--columns: 3;
}
}
.container {
padding: var(--container-padding);
font-size: var(--font-size-base);
}
.grid {
display: grid;
gap: var(--gap-size);
grid-template-columns: repeat(var(--columns), 1fr);
}3. Container Queries (Modern Approach)
Container queries allow components to respond to their container size:
/* Card component that responds to its container */
.card-container {
container-type: inline-size;
}
.card {
padding: 1rem;
border: 1px solid #ddd;
border-radius: 8px;
}
@container (min-width: 300px) {
.card {
padding: 1.5rem;
display: flex;
align-items: center;
gap: 1rem;
}
}
@container (min-width: 500px) {
.card {
padding: 2rem;
flex-direction: column;
text-align: center;
}
.card-title {
font-size: 1.5rem;
}
}Typography and Readability
1. Responsive Typography
Make text readable at all screen sizes:
/* Fluid typography using clamp() */
html {
font-size: clamp(16px, 2.5vw, 20px);
}
/* Responsive typography with media queries */
h1 {
font-size: 2rem; /* 32px */
line-height: 1.2;
}
h2 {
font-size: 1.5rem; /* 24px */
line-height: 1.3;
}
@media (min-width: 768px) {
h1 {
font-size: 2.5rem; /* 40px */
}
h2 {
font-size: 2rem; /* 32px */
}
}
@media (min-width: 1024px) {
h1 {
font-size: 3rem; /* 48px */
}
h2 {
font-size: 2.5rem; /* 40px */
}
}2. Readable Line Length
.content {
max-width: 65ch; /* Optimal reading length */
margin: 0 auto;
line-height: 1.6;
}
@media (max-width: 768px) {
.content {
max-width: 100%;
padding: 0 1rem;
}
}Practical Examples
1. Responsive Header
.header {
background: #333;
color: white;
padding: 1rem;
}
.header-container {
display: flex;
justify-content: space-between;
align-items: center;
}
.logo {
font-size: 1.5rem;
font-weight: bold;
}
.nav-menu {
display: none;
}
.menu-toggle {
display: block;
background: none;
border: none;
color: white;
font-size: 1.5rem;
cursor: pointer;
}
@media (min-width: 768px) {
.menu-toggle {
display: none;
}
.nav-menu {
display: flex;
list-style: none;
gap: 2rem;
margin: 0;
padding: 0;
}
.nav-menu a {
color: white;
text-decoration: none;
padding: 0.5rem 1rem;
border-radius: 4px;
transition: background 0.3s ease;
}
.nav-menu a:hover {
background: #555;
}
}2. Responsive Card Layout
.card-grid {
display: grid;
gap: 2rem;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
padding: 2rem;
}
.card {
background: white;
border-radius: 12px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
overflow: hidden;
transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.card:hover {
transform: translateY(-5px);
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
}
.card-image {
width: 100%;
height: 200px;
object-fit: cover;
}
.card-content {
padding: 1.5rem;
}
.card-title {
font-size: 1.25rem;
font-weight: bold;
margin-bottom: 0.5rem;
color: #333;
}
.card-description {
color: #666;
line-height: 1.6;
margin-bottom: 1rem;
}
.card-button {
background: #007bff;
color: white;
border: none;
padding: 0.75rem 1.5rem;
border-radius: 6px;
cursor: pointer;
transition: background 0.3s ease;
}
.card-button:hover {
background: #0056b3;
}
@media (max-width: 768px) {
.card-grid {
padding: 1rem;
gap: 1rem;
}
.card-content {
padding: 1rem;
}
}3. Responsive Form
.form-container {
max-width: 600px;
margin: 0 auto;
padding: 2rem;
}
.form-group {
margin-bottom: 1.5rem;
}
.form-label {
display: block;
margin-bottom: 0.5rem;
font-weight: 600;
color: #333;
}
.form-input,
.form-textarea,
.form-select {
width: 100%;
padding: 0.75rem;
border: 2px solid #ddd;
border-radius: 6px;
font-size: 1rem;
transition: border-color 0.3s ease;
}
.form-input:focus,
.form-textarea:focus,
.form-select:focus {
outline: none;
border-color: #007bff;
}
.form-textarea {
resize: vertical;
min-height: 120px;
}
.form-row {
display: grid;
gap: 1rem;
}
@media (min-width: 768px) {
.form-row {
grid-template-columns: repeat(2, 1fr);
}
}
.form-button {
background: #007bff;
color: white;
border: none;
padding: 0.75rem 2rem;
border-radius: 6px;
font-size: 1rem;
cursor: pointer;
transition: background 0.3s ease;
}
.form-button:hover {
background: #0056b3;
}
@media (max-width: 480px) {
.form-container {
padding: 1rem;
}
.form-row {
grid-template-columns: 1fr;
}
}Testing Responsive Design
1. Browser Developer Tools
Use browser dev tools to test responsive design:
<!-- Add viewport resizer bookmarklet -->
<a href="javascript:(function(){var%20resizeHandle=document.createElement('div');resizeHandle.style.cssText='position:fixed;top:0;right:0;width:20px;height:20px;background:red;z-index:9999;cursor:ew-resize';document.body.appendChild(resizeHandle);var%20isResizing=false;resizeHandle.addEventListener('mousedown',function(e){isResizing=true;e.preventDefault()});document.addEventListener('mousemove',function(e){if(isResizing){document.body.style.width=e.clientX+'px'}});document.addEventListener('mouseup',function(){isResizing=false})})()">Viewport Resizer</a>2. Common Device Sizes
Test your design with these common viewport sizes:
/* Test breakpoints */
/* iPhone SE: 375x667 */
/* iPhone 12: 390x844 */
/* iPad: 768x1024 */
/* iPad Pro: 1024x1366 */
/* Laptop: 1366x768 */
/* Desktop: 1920x1080 */Best Practices
1. Performance
/* Use efficient media queries */
/* Bad: Repeated properties */
@media (max-width: 768px) {
.element {
color: blue;
font-size: 14px;
}
}
@media (max-width: 480px) {
.element {
color: blue; /* Repeated */
font-size: 12px;
}
}
/* Good: Mobile-first approach */
.element {
color: blue;
font-size: 12px;
}
@media (min-width: 481px) {
.element {
font-size: 14px;
}
}2. Accessibility Considerations
/* Ensure touch targets are large enough */
.button,
.link {
min-height: 44px; /* iOS recommendation */
min-width: 44px;
padding: 12px;
}
/* Respect user preferences */
@media (prefers-reduced-motion: reduce) {
.animated-element {
animation: none;
transition: none;
}
}
@media (prefers-color-scheme: dark) {
.container {
background: #1a1a1a;
color: #ffffff;
}
}3. Progressive Enhancement
/* Base styles that work everywhere */
.container {
width: 100%;
max-width: 1200px;
margin: 0 auto;
padding: 1rem;
}
/* Enhanced for modern browsers */
@supports (display: grid) {
.container {
display: grid;
gap: 2rem;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
}
}External Resources:
Related Tutorials: