Media queries and responsive design

CSS · Practical · 12 min

Most traffic is mobile; responsive CSS is how one codebase serves every screen.

Responsive design means one page that adapts to any screen. It rests on three things: the viewport meta tag in the HTML, flexible layouts (flexbox, grid, %, fr, min()), and media queries for the changes flexibility can't handle.

A media query applies rules only when a condition is true:

@media (width >= 48rem) { .nav { display: flex; } }

The range syntax (width >= 48rem, 30rem <= width < 60rem) is supported in all current browsers and is clearer than the older min-width/max-width form, which means the same thing.

Write mobile-first: base styles for small screens, then width >= queries that add complexity as space grows. Small screens get the simplest CSS, and the cascade stays easy to follow. Choose breakpoints where your content breaks, not by device models. Using em/rem in queries makes them respect user font-size settings.

Media queries also detect user preferences and capabilities:

  • prefers-color-scheme: dark for dark mode,
  • prefers-reduced-motion: reduce to tone down animation, which is important for people with vestibular disorders,
  • hover: hover and pointer: coarse to tell mouse users from touch users,
  • print for print stylesheets.

Many layouts need fewer queries than you'd think: repeat(auto-fit, minmax()), flex-wrap and clamp() adapt continuously. Use media queries for structural changes, like turning a stacked menu into a horizontal bar.

Example

/* mobile first: single column by default */
.layout { display: grid; gap: 1rem; }
.nav-links { display: none; }

@media (width >= 48rem) {             /* tablets and up */
  .layout { grid-template-columns: 220px 1fr; }
  .nav-links { display: flex; gap: 1rem; }
  .menu-button { display: none; }
}

@media (width >= 80rem) {             /* wide screens */
  .layout { grid-template-columns: 260px 1fr 300px; }
}

@media (prefers-reduced-motion: reduce) {
  * { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}

@media (hover: hover) { .card:hover { transform: translateY(-2px); } }
@media print { nav, .ads { display: none; } }

Remember

  • Mobile-first: base styles small, add with width >= queries
  • Pick breakpoints where the content breaks
  • Respect prefers-reduced-motion and prefers-color-scheme
  • Flexible layouts reduce the number of queries you need

Watch out for

  • Desktop-first max-width queries that pile overrides on top of each other.

Check yourself

  1. With mobile-first CSS, where do the styles for the smallest screens go?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: developer.mozilla.org/en-US/docs/Web/CSS/Guides/Media_queries/Using