CSS @media Queries for Width, Height, Color Scheme, and Motion

CSS @media queries let you apply different styles based on the user’s device or preferences. They are one of the main tools for responsive design, helping layouts adapt to screen size, dark mode, and reduced motion settings.

Quick answer: Use @media to target conditions such as viewport width, height, prefers-color-scheme, and prefers-reduced-motion. Write a base style first, then override it only when the media condition matches.

Difficulty: Beginner

You'll understand this better if you know: basic CSS selectors, how the cascade works, and simple values like px, em, and rem.

1. What Is @media Queries (width, height, color-scheme, reduced-motion)?

@media is a CSS at-rule that applies styles only when a media condition is true. The most common conditions check viewport size, but media queries can also respond to user preferences such as dark mode or reduced animation.

These queries do not change the HTML structure. They only change how elements are styled under different conditions.

2. Why @media Queries Matter

Modern sites are used on phones, tablets, laptops, large monitors, and assistive setups. A single fixed layout rarely works well everywhere, so media queries help you build flexible interfaces without separate versions of the same page.

They matter because they improve readability, usability, and accessibility. A responsive navigation bar, a reflowing content grid, or a reduced-motion animation setting can make a site easier to use for many people.

They are especially important when your design must:

3. Basic Syntax or Core Idea

A media query starts with @media, followed by one or more conditions in parentheses. If the condition is true, the rules inside the block apply.

Basic width example

This example changes the page background on wider screens.

body {
  background: white;
  color: black;
}

@media (min-width: 700px) {
  body {
    background: #f5f7ff;
  }
}

The base style applies first. When the viewport is at least 700px wide, the background changes.

Common media features

Here are the most relevant features for this topic:

4. Step-by-Step Examples

Example 1: Mobile-first width breakpoint

Start with a simple stacked layout, then expand it on larger screens. This is the most common responsive approach.

.cards {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1rem;
}

@media (min-width: 768px) {
  .cards {
    grid-template-columns: 1fr 1fr;
  }
}

On small screens, cards stack into one column. On larger screens, the same component becomes two columns without changing the HTML.

Example 2: Height-based adjustment

Height queries are useful for short viewports, such as laptops with browser toolbars or mobile devices in landscape mode.

@media (max-height: 600px) {
  .hero {
    padding-block: 1rem;
  }
}

This reduces vertical spacing when there is not much room. It can prevent important content from being pushed below the fold.

Example 3: Dark mode with color-scheme

Use prefers-color-scheme to adapt colors to the user’s system preference.

body {
  background: white;
  color: #111;
}

@media (prefers-color-scheme: dark) {
  body {
    background: #121212;
    color: #f3f3f3;
  }
}

This does not create a manual theme switch. It respects the operating system or browser preference automatically.

Example 4: Reduced motion

When motion is present, users who prefer less animation should get a calmer experience.

.spinner {
  animation: spin 1s linear infinite;
}

@media (prefers-reduced-motion: reduce) {
  .spinner {
    animation: none;
  }
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

This keeps the interface usable for people who are sensitive to movement, while still allowing the animation for others.

5. Practical Use Cases

Media queries are useful in many real projects. Common situations include:

They are best when the visual change depends on the environment, not on the data being shown.

6. Common Mistakes

Mistake 1: Using max-width and min-width in the wrong order

It is easy to write breakpoints that fight each other when the cascade is not planned carefully. The order of the rules matters as much as the conditions themselves.

Problem: The wider-screen rule appears first, so the smaller-screen rule overrides it later and the layout does not behave as expected.

.layout {
  grid-template-columns: 1fr;
}

@media (min-width: 900px) {
  .layout {
    grid-template-columns: 1fr 1fr;
  }
}

@media (max-width: 600px) {
  .layout {
    grid-template-columns: 1fr;
  }
}

Fix: Use a mobile-first approach and place larger breakpoint rules after the base styles.

.layout {
  grid-template-columns: 1fr;
}

@media (min-width: 900px) {
  .layout {
    grid-template-columns: 1fr 1fr;
  }
}

The corrected version works because the base layout is defined first and the larger-screen enhancement is applied later.

Mistake 2: Expecting dark mode to work without a fallback

Some browsers or users may not support the color-scheme preference, so your styles should still look good without it.

Problem: The page only defines dark-mode styles, so in browsers that do not match the media query the content may remain unreadable.

@media (prefers-color-scheme: dark) {
  body {
    background: #000;
    color: #fff;
  }
}

Fix: Write sensible default colors first, then override them for dark mode.

body {
  background: #fff;
  color: #111;
}

@media (prefers-color-scheme: dark) {
  body {
    background: #000;
    color: #fff;
  }
}

The fallback ensures the page stays readable even when the preference is unavailable.

Mistake 3: Removing all transitions instead of reducing motion carefully

Reduced motion does not always mean every animation must disappear. Sometimes a simple change in behavior is enough.

Problem: This code disables all motion, including useful transitions that help users understand changes in state.

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

Fix: Target the motion-heavy elements and reduce only what is necessary.

@media (prefers-reduced-motion: reduce) {
  .spinner {
    animation: none;
  }

  .menu {
    transition: none;
  }
}

The corrected version preserves useful interface feedback while avoiding unnecessary movement.

7. Best Practices

Practice 1: Start with a solid base style

Media queries should enhance a working layout, not rescue a broken one. A clean default makes the responsive rules easier to manage.

.sidebar {
  width: 100%;
}

@media (min-width: 900px) {
  .sidebar {
    width: 320px;
  }
}

This makes the default experience reliable on small screens and keeps larger-screen changes easy to understand.

Practice 2: Use breakpoints for content, not device names

It is better to choose breakpoints where the layout starts to look bad than to target specific phone or laptop models.

@media (min-width: 48rem) {
  .article-layout {
    display: grid;
    grid-template-columns: 2fr 1fr;
  }
}

Using content-driven breakpoints usually produces a more durable design because it responds to layout needs rather than device labels.

Practice 3: Respect user preferences by default

Color scheme and reduced motion are accessibility features, not decorative extras. They should be considered part of the core experience.

:root {
  color-scheme: light dark;
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
}

This approach supports the browser’s built-in UI styling and avoids forcing animated scrolling on people who asked for less motion.

8. Limitations and Edge Cases

If a media query seems to be ignored, check whether another rule later in the stylesheet is overriding it. The issue is often the cascade, not the media feature itself.

9. Practical Mini Project

Here is a small responsive feature card that changes layout with width, switches colors for dark mode, and removes animation for reduced-motion users.

.feature-card {
  display: grid;
  gap: 1rem;
  padding: 1rem;
  border: 1px solid #d7d7d7;
  border-radius: 0.75rem;
  background: #ffffff;
  color: #111111;
}

.feature-card__icon {
  width: 3rem;
  height: 3rem;
  animation: pulse 1.5s ease-in-out infinite;
}

@media (min-width: 50rem) {
  .feature-card {
    grid-template-columns: auto 1fr;
    align-items: center;
  }
}

@media (prefers-color-scheme: dark) {
  .feature-card {
    background: #1b1b1b;
    color: #f5f5f5;
    border-color: #3a3a3a;
  }
}

@media (prefers-reduced-motion: reduce) {
  .feature-card__icon {
    animation: none;
  }
}

@keyframes pulse {
  0%, 100% {
    transform: scale(1);
  }
  50% {
    transform: scale(1.08);
  }
}

This example shows how multiple media queries can work together in one component. The base card works everywhere, and each query adds one targeted improvement.

10. Key Points

11. Practice Exercise

Create a simple page section that responds to three conditions:

Expected output: A layout that is readable on small screens, expands on larger screens, supports dark mode, and avoids motion when requested.

Hint: Start with the base layout first, then add one media query for width, one for color scheme, and one for reduced motion.

Solution:

.panel {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1rem;
  padding: 1rem;
  background: #ffffff;
  color: #111111;
}

.panel__badge {
  animation: bounce 1s ease-in-out infinite;
}

@media (min-width: 800px) {
  .panel {
    grid-template-columns: 1fr 1fr;
  }
}

@media (prefers-color-scheme: dark) {
  .panel {
    background: #1e1e1e;
    color: #f0f0f0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .panel__badge {
    animation: none;
  }
}

@keyframes bounce {
  0%, 100% {
    transform: translateY(0);
  }
  50% {
    transform: translateY(-4px);
  }
}

12. Final Summary

CSS @media queries let you adapt styles to viewport size, screen height, and user preferences such as dark mode or reduced motion. They are essential for responsive design because they let one set of HTML and CSS work well in many environments.

The most reliable approach is to create a strong default style first, then add media queries as targeted enhancements. Use width queries for layout changes, color-scheme queries for theme support, and reduced-motion queries for accessibility-aware motion control.

As you practice, pay attention to the cascade, choose breakpoints based on content, and test on both small and large screens. If you want to go further, the next step is learning how media queries work alongside flexible layouts such as CSS Grid and Flexbox.