Responsive Design

Intermediate 1.5 hours read Last updated: Dec 8, 2024

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;
    }
}