3.6: Responsive Design & Media Queries

Create websites that adapt seamlessly to different screen sizes using responsive design principles and media queries. Learn mobile-first design, breakpoints, and flexible layouts for optimal user experience across all devices.

1. What is Responsive Design?

Responsive Web Design (RWD) means websites adapt to different screen sizes and devices.

The Three Pillars of RWD

1. Fluid Grids    →  Flexible layouts using percentages/fr units
2. Flexible Media →  Images and videos scale with containers
3. Media Queries  →  Apply styles based on device characteristics

Why Responsive Design?

Device landscape:

  • šŸ“± Mobile phones (320px - 480px)
  • šŸ“± Tablets (768px - 1024px)
  • šŸ’» Laptops (1024px - 1440px)
  • šŸ–„ļø Desktops (1440px+)

Benefits:

  • āœ… One codebase for all devices
  • āœ… Better user experience
  • āœ… Improved SEO (Google favors mobile-friendly sites)
  • āœ… Future-proof design

2. The Viewport Meta Tag

Essential for responsive design - tells browsers how to handle page dimensions.

Required Meta Tag

<meta name="viewport" content="width=device-width, initial-scale=1.0">

Breakdown:

  • width=device-width - Match screen width
  • initial-scale=1.0 - No zoom (100% scale)

Without viewport tag:

Mobile browser shows desktop version (tiny, requires zooming)

With viewport tag:

Mobile browser shows mobile-optimized version (readable)

Viewport Options

<!-- Standard (recommended) -->
<meta name="viewport" content="width=device-width, initial-scale=1.0">

<!-- Prevent zooming (not recommended for accessibility) -->
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">

<!-- Allow zooming (better for accessibility) -->
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0">

Best practice: Allow zooming for accessibility


3. Media Queries

Apply styles based on device characteristics.

Basic Media Query Syntax

/* Base styles (mobile first) */
body {
  font-size: 16px;
  padding: 10px;
}

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

/* Desktop and up */
@media (min-width: 1024px) {
  body {
    font-size: 20px;
    padding: 40px;
  }
}

Media Query Features

/* Width */
@media (min-width: 768px) { }  /* Wider than 768px */
@media (max-width: 767px) { }  /* Narrower than 767px */
@media (width: 768px) { }      /* Exactly 768px (rare) */

/* Height */
@media (min-height: 600px) { }
@media (max-height: 800px) { }

/* Orientation */
@media (orientation: landscape) { }
@media (orientation: portrait) { }

/* Resolution */
@media (min-resolution: 192dpi) { } /* High DPI screens */
@media (min-resolution: 2dppx) { }  /* Retina displays */

/* Aspect ratio */
@media (aspect-ratio: 16/9) { }
@media (min-aspect-ratio: 16/9) { }

/* Color */
@media (color) { }              /* Color display */
@media (min-color: 8) { }       /* At least 8 bits per color */

/* Hover capability */
@media (hover: hover) { }       /* Can hover (mouse) */
@media (hover: none) { }        /* Cannot hover (touch) */

/* Pointer precision */
@media (pointer: fine) { }      /* Precise pointer (mouse) */
@media (pointer: coarse) { }    /* Imprecise pointer (touch) */

/* Prefers color scheme */
@media (prefers-color-scheme: dark) { }
@media (prefers-color-scheme: light) { }

/* Prefers reduced motion */
@media (prefers-reduced-motion: reduce) {
  * {
    animation: none !important;
    transition: none !important;
  }
}

Combining Media Queries

/* AND operator */
@media (min-width: 768px) and (max-width: 1024px) {
  /* Tablet only */
}

@media (min-width: 768px) and (orientation: landscape) {
  /* Tablet landscape */
}

/* OR operator (comma) */
@media (max-width: 767px), (orientation: portrait) {
  /* Mobile OR portrait */
}

/* NOT operator */
@media not all and (min-width: 768px) {
  /* Not tablet/desktop */
}

4. Breakpoints

Screen widths where layout changes.

Common Breakpoints

/* Mobile First Approach */

/* Extra small devices (phones, 0-575px) */
/* Base styles here */

/* 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) { }

/* XX large devices (larger desktops, 1400px and up) */
@media (min-width: 1400px) { }

Bootstrap-Style Breakpoints

/* Extra small (xs) - default, no media query */

/* Small (sm) */
@media (min-width: 576px) { }

/* Medium (md) */
@media (min-width: 768px) { }

/* Large (lg) */
@media (min-width: 992px) { }

/* Extra large (xl) */
@media (min-width: 1200px) { }

/* Extra extra large (xxl) */
@media (min-width: 1400px) { }

Custom Breakpoints

/* Based on your design needs */
@media (min-width: 480px) { }   /* Large phones */
@media (min-width: 768px) { }   /* Tablets */
@media (min-width: 1024px) { }  /* Small laptops */
@media (min-width: 1280px) { }  /* Laptops */
@media (min-width: 1440px) { }  /* Desktops */
@media (min-width: 1920px) { }  /* Large desktops */

5. Mobile-First vs Desktop-First

Start with mobile styles, add complexity for larger screens.

/* Base: Mobile */
.container {
  width: 100%;
  padding: 15px;
}

.grid {
  display: block; /* Stack on mobile */
}

/* Tablet and up */
@media (min-width: 768px) {
  .container {
    max-width: 720px;
    margin: 0 auto;
  }

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

/* Desktop and up */
@media (min-width: 1024px) {
  .container {
    max-width: 960px;
  }

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

Advantages:

  • āœ… Better performance (mobile loads less code)
  • āœ… Progressive enhancement
  • āœ… Easier to maintain

Desktop-First

Start with desktop styles, scale down for mobile.

/* Base: Desktop */
.container {
  max-width: 1200px;
  margin: 0 auto;
  padding: 40px;
}

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

/* Tablet and down */
@media (max-width: 1023px) {
  .container {
    max-width: 960px;
    padding: 30px;
  }

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

/* Mobile and down */
@media (max-width: 767px) {
  .container {
    padding: 15px;
  }

  .grid {
    display: block;
  }
}

6. Responsive Units

Relative Units

/* em - Relative to parent font-size */
.parent {
  font-size: 16px;
}

.child {
  font-size: 1.5em; /* 24px (16 Ɨ 1.5) */
  padding: 1em;     /* 24px (own font-size) */
}

/* rem - Relative to root font-size */
:root {
  font-size: 16px;
}

.element {
  font-size: 1.5rem; /* 24px (16 Ɨ 1.5) */
  margin: 2rem;      /* 32px (16 Ɨ 2) */
}

/* Percentage - Relative to parent */
.parent {
  width: 1000px;
}

.child {
  width: 50%; /* 500px */
}

/* Viewport units */
.hero {
  width: 100vw;  /* 100% of viewport width */
  height: 100vh; /* 100% of viewport height */
}

.sidebar {
  width: 30vw;   /* 30% of viewport width */
}

.text {
  font-size: 2vw; /* 2% of viewport width (careful with this) */
}

/* vmin/vmax */
.element {
  width: 50vmin;  /* 50% of smaller viewport dimension */
  height: 50vmax; /* 50% of larger viewport dimension */
}

Unit Comparison

/* Pixel - Fixed */
.box {
  width: 300px; /* Always 300px */
}

/* Percentage - Fluid */
.box {
  width: 50%; /* 50% of parent */
}

/* rem - Scalable */
.box {
  width: 20rem; /* Scales with root font-size */
}

/* fr - Grid fraction */
.grid {
  display: grid;
  grid-template-columns: 1fr 2fr; /* 1:2 ratio */
}

Best Practices

Use rem for:

  • āœ… Font sizes
  • āœ… Spacing (margin, padding)
  • āœ… Consistent sizing

Use % for:

  • āœ… Widths
  • āœ… Fluid layouts

Use vw/vh for:

  • āœ… Full-screen sections
  • āœ… Hero images

Use px for:

  • āœ… Borders
  • āœ… Small fixed sizes

7. Responsive Images

Flexible Images

/* Basic responsive image */
img {
  max-width: 100%;
  height: auto;
}

/* Maintain aspect ratio */
.image-container {
  width: 100%;
  max-width: 600px;
}

.image-container img {
  width: 100%;
  height: auto;
  display: block;
}

Responsive Background Images

.hero {
  background-image: url('hero-mobile.jpg');
  background-size: cover;
  background-position: center;
  min-height: 300px;
}

@media (min-width: 768px) {
  .hero {
    background-image: url('hero-tablet.jpg');
    min-height: 500px;
  }
}

@media (min-width: 1024px) {
  .hero {
    background-image: url('hero-desktop.jpg');
    min-height: 600px;
  }
}

HTML Picture Element

<picture>
  <source media="(min-width: 1024px)" srcset="large.jpg">
  <source media="(min-width: 768px)" srcset="medium.jpg">
  <img src="small.jpg" alt="Description">
</picture>

Srcset for Retina Displays

<img
  src="image-1x.jpg"
  srcset="image-1x.jpg 1x, image-2x.jpg 2x, image-3x.jpg 3x"
  alt="Description">

8. Responsive Typography

Fluid Typography

/* Fixed sizes with breakpoints */
body {
  font-size: 14px;
}

@media (min-width: 768px) {
  body {
    font-size: 16px;
  }
}

@media (min-width: 1024px) {
  body {
    font-size: 18px;
  }
}

Clamp Function (Modern)

/* Fluid typography with constraints */
h1 {
  font-size: clamp(24px, 5vw, 72px);
  /* min: 24px, preferred: 5vw, max: 72px */
}

body {
  font-size: clamp(16px, 1vw + 14px, 20px);
}

Responsive Line Height

.text {
  font-size: 16px;
  line-height: 1.6; /* Unitless - scales with font-size */
}

@media (min-width: 768px) {
  .text {
    font-size: 18px;
    /* line-height auto-scales to 28.8px (18 Ɨ 1.6) */
  }
}

9. Container Queries (Modern)

Apply styles based on container size (not viewport).

.card-container {
  container-type: inline-size;
  container-name: card;
}

.card {
  display: grid;
  grid-template-columns: 1fr;
}

/* When container is 500px or wider */
@container card (min-width: 500px) {
  .card {
    grid-template-columns: 200px 1fr;
  }
}

10. Responsive Layout Patterns

Responsive Navigation

/* Mobile: Hamburger menu */
.nav {
  display: none;
}

.nav-toggle {
  display: block;
}

.nav.active {
  display: flex;
  flex-direction: column;
}

/* Desktop: Horizontal menu */
@media (min-width: 768px) {
  .nav {
    display: flex !important;
    flex-direction: row;
  }

  .nav-toggle {
    display: none;
  }
}

Responsive Grid

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

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

/* Desktop: 4 columns */
@media (min-width: 1024px) {
  .grid {
    grid-template-columns: repeat(4, 1fr);
  }
}

Responsive Cards

.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 24px;
}

/* No media queries needed! */

11. Practical Examples

Responsive Container

.container {
  width: 100%;
  padding: 0 15px;
  margin: 0 auto;
}

@media (min-width: 576px) {
  .container {
    max-width: 540px;
  }
}

@media (min-width: 768px) {
  .container {
    max-width: 720px;
  }
}

@media (min-width: 992px) {
  .container {
    max-width: 960px;
  }
}

@media (min-width: 1200px) {
  .container {
    max-width: 1140px;
  }
}

Responsive Hero Section

.hero {
  padding: 40px 20px;
  text-align: center;
}

.hero h1 {
  font-size: 32px;
  margin-bottom: 20px;
}

.hero p {
  font-size: 16px;
}

@media (min-width: 768px) {
  .hero {
    padding: 80px 40px;
  }

  .hero h1 {
    font-size: 48px;
  }

  .hero p {
    font-size: 18px;
  }
}

@media (min-width: 1024px) {
  .hero {
    padding: 120px 60px;
  }

  .hero h1 {
    font-size: 64px;
  }

  .hero p {
    font-size: 20px;
  }
}

12. Testing Responsive Design

Browser DevTools

Chrome DevTools:

  1. F12 → Toggle device toolbar (Ctrl+Shift+M)
  2. Select device preset or custom dimensions
  3. Test different screen sizes
  4. Throttle network speed

Firefox Responsive Design Mode:

  1. F12 → Responsive Design Mode (Ctrl+Shift+M)
  2. Rotate device orientation
  3. Touch simulation

Testing Checklist

  • Test all breakpoints
  • Check navigation on mobile
  • Verify images scale properly
  • Test forms on touch devices
  • Check text readability
  • Test landscape and portrait
  • Verify touch targets (44Ɨ44px min)

13. Practical Exercises

Exercise 3.6.1: Responsive Navigation

Create a navigation that:

  • Shows hamburger menu on mobile
  • Expands to horizontal menu on desktop (768px+)
  • Has smooth transition

Exercise 3.6.2: Responsive Card Grid

Build a card grid with:

  • 1 column on mobile (< 576px)
  • 2 columns on tablet (576px - 991px)
  • 3 columns on desktop (992px+)

Exercise 3.6.3: Responsive Hero

Create a hero section that:

  • Stacks content on mobile
  • Side-by-side on tablet+
  • Different background images per breakpoint

Exercise 3.6.4: Fluid Typography

Implement fluid typography using:

  • clamp() for headings
  • Responsive base font-size
  • Unitless line-height

14. Knowledge Check

Question 1: What does the viewport meta tag do?

Show answer It tells the browser how to control the page's dimensions and scaling, making the page responsive to different screen sizes.

Question 2: What's the difference between mobile-first and desktop-first?

Show answer Mobile-first starts with mobile styles and uses min-width media queries to add complexity. Desktop-first starts with desktop styles and uses max-width to simplify for mobile.

Question 3: When should you use rem vs em?

Show answer Use rem for consistent sizing relative to root. Use em when you want sizing relative to the parent element.

Question 4: What are common responsive breakpoints?

Show answer Common breakpoints: 576px (small), 768px (medium/tablet), 992px (large), 1200px (extra large).

Question 5: How do you make images responsive?

Show answer max-width: 100%; height: auto; ensures images scale down but never exceed their container or original size.

Question 6: What's the difference between vw and %?

Show answer vw is relative to viewport width (1vw = 1% of viewport). % is relative to the parent element's width.

15. Common Mistakes to Avoid

āŒ Forgetting Viewport Meta Tag

<!-- Bad - not responsive -->
<head>
  <title>Page</title>
</head>

<!-- Good - responsive -->
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Page</title>
</head>

āŒ Using max-width with Mobile-First

/* Bad - desktop-first approach */
@media (max-width: 767px) {
  /* Mobile styles */
}

/* Good - mobile-first approach */
/* Mobile base styles */
@media (min-width: 768px) {
  /* Desktop styles */
}

āŒ Fixed Widths Without Max-Width

/* Bad - breaks on small screens */
.container {
  width: 1200px;
}

/* Good - responsive */
.container {
  width: 100%;
  max-width: 1200px;
}

16. Key Takeaways

āœ… Viewport meta tag - Required for responsive design āœ… Mobile-first - Start small, add complexity for larger screens āœ… Media queries - Apply styles based on screen characteristics āœ… Breakpoints - Common: 576px, 768px, 992px, 1200px āœ… Responsive units - rem, %, vw/vh for fluid layouts āœ… Flexible images - max-width: 100%; height: auto; āœ… Fluid typography - Use clamp() or responsive font-sizes āœ… Container queries - Style based on container, not viewport āœ… Test thoroughly - Use DevTools and real devices āœ… Progressive enhancement - Build up from basic to advanced


17. Further Resources

Official Documentation:

Tools:

Articles:


Next Steps

Great work! You can now create responsive layouts that work beautifully on any device.

In Lesson 3.7: Typography & Colors, you'll learn to create beautiful, readable text and compelling color schemes.