Responsive Design

Media queries, mobile-first, and fluid layouts

What is Responsive Design?

Responsive design is an approach that ensures your website looks great and functions well on any device—from phones to tablets to large desktop monitors. Instead of creating separate mobile and desktop versions, you build one flexible layout that adapts to different screen sizes.

The three pillars of responsive design are: fluid grids (flexible layouts), flexible images (that scale appropriately), and media queries (CSS that applies different styles at different screen sizes).

The Viewport Meta Tag

This essential HTML tag tells mobile browsers how to scale your page:

❌ Without Viewport Tag

Mobile browsers assume desktop width (980px), page appears tiny and zoomed out

✓ With Viewport Tag

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

Page uses actual device width, perfect starting zoom

Media Queries

Media queries apply styles based on screen characteristics like width, height, or orientation:

Basic Media Query Syntax

/* Apply these styles when screen is at least 768px wide */
@media (min-width: 768px) {
  .container {
    max-width: 720px;
    padding: 32px;
  }
}

/* Max-width (less common with mobile-first) */
@media (max-width: 767px) {
  .sidebar {
    display: none;
  }
}

/* Orientation */
@media (orientation: landscape) {
  .hero {
    height: 50vh;
  }
}

Common Breakpoints

Mobile: 0 - 639px 📱
Tablet: 640px - 1023px 📱 landscape / small tablets
Desktop: 1024px - 1279px 💻
Large Desktop: 1280px+ 🖥️

Mobile-First Approach

Start with mobile styles, then enhance for larger screens. This is better for performance and forces you to prioritize content.

❌ Desktop-First (Not Recommended)

/* Desktop styles first */
.nav {
  display: flex;
  gap: 24px;
}

/* Override for mobile */
@media (max-width: 768px) {
  .nav {
    display: block;
    gap: 0;
  }
}

Mobile inherits desktop CSS, then overrides it

✓ Mobile-First (Recommended)

/* Mobile styles first */
.nav {
  display: block;
}

/* Enhance for desktop */
@media (min-width: 768px) {
  .nav {
    display: flex;
    gap: 24px;
  }
}

Start simple, progressively enhance

Fluid Typography

Make text scale smoothly across screen sizes using modern CSS functions:

Using clamp() - The Modern Way

This heading scales fluidly

Resize your browser to see it adapt

h1 {
  font-size: clamp(1.5rem, 4vw, 3rem);
  /* min: 1.5rem, preferred: 4vw, max: 3rem */
  /* Smoothly scales between min and max */
}

p {
  font-size: clamp(1rem, 2.5vw, 1.125rem);
}

/* Fluid spacing too! */
.section {
  padding: clamp(1rem, 5vw, 3rem);
}

Media Query Approach (Traditional)

/* Mobile */
h1 { font-size: 24px; }

/* Tablet */
@media (min-width: 768px) {
  h1 { font-size: 32px; }
}

/* Desktop */
@media (min-width: 1024px) {
  h1 { font-size: 40px; }
}

Responsive Images

Images need special attention to look good and load efficiently on all devices:

Basic Responsive Image

Demo
img {
  max-width: 100%;  /* Never exceed container */
  height: auto;     /* Maintain aspect ratio */
  display: block;   /* Remove bottom space */
}

Object-fit for Cropping

Cover

object-fit: cover

Contain

object-fit: contain

Fill

object-fit: fill

.hero-image {
  width: 100%;
  height: 400px;
  object-fit: cover;        /* Crop to fill */
  object-position: center;  /* Focus point */
}

Responsive Images with srcset

<img 
  src="image-800.jpg"
  srcset="
    image-400.jpg 400w,
    image-800.jpg 800w,
    image-1200.jpg 1200w
  "
  sizes="(max-width: 600px) 100vw, 50vw"
  alt="Description"
/>
/* Browser picks best image based on screen size */

Responsive Layout Patterns

Stack to Row

Mobile (stacked):

Item 1
Item 2
Item 3

Desktop (row):

Item 1
Item 2
Item 3
.container {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

@media (min-width: 768px) {
  .container {
    flex-direction: row;
  }
}

Responsive Grid (No Media Queries!)

1
2
3
4
.grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 24px;
}
/* Automatically adjusts columns based on available space! */

Hide/Show Elements

/* Hide on mobile, show on desktop */
.desktop-only {
  display: none;
}
@media (min-width: 1024px) {
  .desktop-only {
    display: block;
  }
}

/* Show on mobile, hide on desktop */
.mobile-only {
  display: block;
}
@media (min-width: 1024px) {
  .mobile-only {
    display: none;
  }
}

Container Queries (Modern CSS)

The future of responsive design—style elements based on their container size, not the viewport:

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

/* Style based on container width, not viewport */
@container card (min-width: 400px) {
  .card {
    display: flex;
    gap: 20px;
  }
}

@container card (min-width: 600px) {
  .card {
    font-size: 1.125rem;
  }
}

⚡ Supported in all modern browsers (2023+)

⚠️ Common Responsive Pitfalls

  • Fixed widths: Avoid width: 600px. Use max-width: 600px or percentages
  • px for everything: Use relative units (rem, em, %, vw) for better scaling
  • Ignoring touch targets: Buttons should be at least 44×44px for mobile
  • Horizontal scrolling: Ensure content never forces horizontal scroll on mobile
  • Not testing on real devices: Simulators don't catch everything

✓ Responsive Design Checklist

  • ✓ Include viewport meta tag
  • ✓ Use mobile-first approach with min-width media queries
  • ✓ Make all images responsive (max-width: 100%)
  • ✓ Use relative units (rem, em, %) instead of px
  • ✓ Test on actual mobile devices, not just browser resize
  • ✓ Ensure touch targets are large enough (44×44px minimum)
  • ✓ Consider using CSS Grid with auto-fit for responsive layouts
  • ✓ Optimize images for different screen sizes (use srcset)