📱 Responsive Design

Responsive design ensures your website looks great and works well on all devices - from mobile phones to tablets to desktop computers.

Why Responsive Design?

📊 The Stats
  • Over 60% of web traffic comes from mobile devices
  • Google prioritizes mobile-friendly sites in search rankings
  • Users expect websites to work on any device
  • One codebase works everywhere (no separate mobile site)

The Viewport Meta Tag

Always include this in your <head>:

<meta name="viewport" content="width=device-width, initial-scale=1.0">
Property Purpose
width=device-width Sets viewport width to device screen width
initial-scale=1.0 Sets initial zoom level (1 = 100%)
⚠️ Critical

Without this meta tag, mobile browsers will render your page at desktop width and then shrink it to fit, making text tiny and unreadable.

Mobile-First Approach

Mobile-first means designing for mobile devices first, then adding complexity for larger screens.

Design Progression
1. Mobile (320px-480px)    ← Start here (smallest)
   ↓
2. Tablet (768px-1024px)   ← Add more features
   ↓
3. Desktop (1200px+)       ← Full experience
Mobile-First CSS
/* Base styles: Mobile (default) */
.container {
  padding: 10px;
  font-size: 16px;
}

/* Tablet and up */
@media (min-width: 768px) {
  .container {
    padding: 20px;
    font-size: 18px;
  }
}

/* Desktop and up */
@media (min-width: 1200px) {
  .container {
    padding: 30px;
    font-size: 20px;
  }
}

Media Queries

Media queries let you apply CSS styles based on device characteristics like screen width.

Basic Syntax

@media (condition) {
  /* Styles applied when condition is true */
}

Common Breakpoints

Device Width Range Media Query
Mobile 320px - 480px @media (max-width: 480px)
Tablet 768px - 1024px @media (min-width: 768px)
Desktop 1200px+ @media (min-width: 1200px)
Large Desktop 1920px+ @media (min-width: 1920px)
Responsive Navigation Example
/* Mobile: Stacked navigation */
.nav {
  display: flex;
  flex-direction: column;
}

.nav-item {
  padding: 15px;
  border-bottom: 1px solid #ddd;
}

/* Tablet and up: Horizontal navigation */
@media (min-width: 768px) {
  .nav {
    flex-direction: row;
    justify-content: space-around;
  }

  .nav-item {
    border-bottom: none;
  }
}

Media Query Operators

/* Minimum width (mobile-first) */
@media (min-width: 768px) {
  /* Styles for 768px and wider */
}

/* Maximum width */
@media (max-width: 767px) {
  /* Styles for 767px and narrower */
}

/* Range (between two widths) */
@media (min-width: 768px) and (max-width: 1024px) {
  /* Styles for tablets only */
}

/* Orientation */
@media (orientation: landscape) {
  /* Styles for landscape mode */
}

/* Multiple conditions */
@media (min-width: 768px) and (orientation: portrait) {
  /* Styles for portrait tablets */
}

Responsive Units

Relative Units

Unit Relative To Best For
% Parent element Widths, fluid layouts
em Parent font size Padding, margin
rem Root font size Font sizes, spacing
vw Viewport width Full-width sections
vh Viewport height Full-height sections
vmin Smaller viewport dimension Responsive elements
vmax Larger viewport dimension Responsive elements
/* Fluid width */
.container {
  width: 90%;      /* 90% of parent */
  max-width: 1200px; /* But never larger than 1200px */
}

/* Responsive font size */
html {
  font-size: 16px; /* Base size */
}

h1 {
  font-size: 2rem;  /* 32px (2 × 16px) */
}

/* Full viewport height */
.hero {
  height: 100vh; /* Always full screen height */
}

Responsive Images

Fluid Images

/* Make images scale with container */
img {
  max-width: 100%;  /* Never larger than container */
  height: auto;     /* Maintain aspect ratio */
  display: block;   /* Remove inline spacing */
}

Picture Element

Different images for different screens
<picture>
  <!-- Large screens: use high-res image -->
  <source media="(min-width: 1200px)" srcset="hero-large.jpg">

  <!-- Medium screens: use medium image -->
  <source media="(min-width: 768px)" srcset="hero-medium.jpg">

  <!-- Small screens: use small image (default) -->
  <img src="hero-small.jpg" alt="Hero image">
</picture>

Srcset Attribute

<!-- Browser chooses best image based on screen density -->
<img
  src="image.jpg"
  srcset="image-small.jpg 480w,
          image-medium.jpg 768w,
          image-large.jpg 1200w"
  sizes="(max-width: 768px) 100vw,
         (max-width: 1200px) 50vw,
         33vw"
  alt="Responsive image"
>

Responsive Typography

Using clamp()

/* Fluid font size that scales with viewport */
h1 {
  font-size: clamp(1.5rem, 5vw, 3rem);
  /*            min     ideal   max */
  /* Never smaller than 1.5rem */
  /* Never larger than 3rem */
  /* Grows with viewport between those values */
}

Responsive Font Scales

/* Mobile font sizes */
body   { font-size: 16px; }
h1     { font-size: 24px; }
h2     { font-size: 20px; }
h3     { font-size: 18px; }

/* Desktop font sizes */
@media (min-width: 1200px) {
  body { font-size: 18px; }
  h1   { font-size: 48px; }
  h2   { font-size: 36px; }
  h3   { font-size: 24px; }
}

Responsive Layout Patterns

1. Column Drop

/* Mobile: Stacked columns */
.grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 20px;
}

/* Tablet: Two columns */
@media (min-width: 768px) {
  .grid {
    grid-template-columns: 1fr 1fr;
  }
}

/* Desktop: Three columns */
@media (min-width: 1200px) {
  .grid {
    grid-template-columns: 1fr 1fr 1fr;
  }
}

2. Flexbox Wrapping

.flex-container {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
}

.flex-item {
  flex: 1 1 300px; /* Grow, shrink, min 300px */
}

3. Auto-Fit Grid

.grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 20px;
  /* Automatically fits as many 250px+ columns as possible */
}

Common Responsive Patterns

Hide/Show Elements

/* Show on mobile, hide on desktop */
.mobile-only {
  display: block;
}

@media (min-width: 768px) {
  .mobile-only {
    display: none;
  }
}

/* Hide on mobile, show on desktop */
.desktop-only {
  display: none;
}

@media (min-width: 768px) {
  .desktop-only {
    display: block;
  }
}

Responsive Spacing

.section {
  padding: 20px; /* Mobile */
}

@media (min-width: 768px) {
  .section {
    padding: 40px; /* Tablet */
  }
}

@media (min-width: 1200px) {
  .section {
    padding: 60px; /* Desktop */
  }
}

Testing Responsive Design

🔍 Testing Tools
  • Browser DevTools: Press F12, click device icon
  • Chrome DevTools: Toggle device toolbar (Ctrl+Shift+M)
  • Firefox Responsive Mode: Ctrl+Shift+M
  • Real Devices: Test on actual phones/tablets
  • Online Tools: BrowserStack, Responsinator

Best Practices

💡 Responsive Design Tips
  • ✅ Always include viewport meta tag
  • ✅ Design mobile-first, then scale up
  • ✅ Use relative units (%, rem, em)
  • ✅ Make images flexible with max-width: 100%
  • ✅ Test on real devices, not just DevTools
  • ✅ Use Flexbox/Grid for layouts
  • ✅ Touch targets should be at least 44×44px
  • ✅ Keep content readable without zooming
  • ❌ Don't use fixed widths in pixels
  • ❌ Don't rely on hover states (mobile has no hover)

Complete Responsive Example

HTML
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Responsive Page</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <header class="header">
    <h1>My Site</h1>
    <nav class="nav">
      <a href="#">Home</a>
      <a href="#">About</a>
      <a href="#">Contact</a>
    </nav>
  </header>

  <main class="container">
    <div class="grid">
      <div class="card">Card 1</div>
      <div class="card">Card 2</div>
      <div class="card">Card 3</div>
    </div>
  </main>
</body>
</html>
CSS
/* Mobile-first base styles */
* {
  box-sizing: border-box;
}

body {
  margin: 0;
  font-family: Arial, sans-serif;
}

.container {
  width: 90%;
  max-width: 1200px;
  margin: 0 auto;
  padding: 20px;
}

/* Mobile: Stacked navigation */
.nav {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

/* Mobile: Single column grid */
.grid {
  display: grid;
  gap: 20px;
}

.card {
  padding: 20px;
  background: #f0f0f0;
  border-radius: 8px;
}

/* Tablet: 768px and up */
@media (min-width: 768px) {
  .nav {
    flex-direction: row;
    justify-content: space-around;
  }

  .grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

/* Desktop: 1200px and up */
@media (min-width: 1200px) {
  .grid {
    grid-template-columns: repeat(3, 1fr);
  }
}

Summary

📚 What you learned
  • Why responsive design is essential
  • How to use the viewport meta tag
  • Mobile-first design approach
  • Media queries and breakpoints
  • Responsive units (%, rem, vw, vh)
  • Responsive images techniques
  • Common responsive patterns
  • Testing and best practices