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.
- width and height help you adapt layouts to the available screen space.
- prefers-color-scheme lets you support light and dark themes.
- prefers-reduced-motion helps reduce animation for users who request it.
- Media queries work through the normal CSS cascade, so the order of rules still matters.
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:
- stack columns on small screens and spread them on larger screens,
- adjust spacing and typography for short or narrow viewports,
- respect dark mode or light mode preferences,
- avoid motion that may cause discomfort.
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:
- min-width and max-width for viewport width.
- min-height and max-height for viewport height.
- prefers-color-scheme for light or dark preference.
- prefers-reduced-motion for reduced animation preference.
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:
- Switching a product grid from one column on phones to multiple columns on larger screens.
- Changing a sidebar into a top navigation bar on narrow screens.
- Reducing hero padding on short viewports so the main content stays visible.
- Using dark colors when the user prefers dark mode.
- Turning off decorative motion for users who prefer reduced motion.
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
- Media queries only react to the environment they can detect. They do not know the actual device model or the user’s task.
- Viewport width is not always the same as physical screen width. Browser zoom, scrollbars, and mobile browser UI can affect the usable space.
- Height-based queries can be unpredictable on mobile because browser chrome may expand or collapse as the user scrolls.
- prefers-color-scheme depends on user and browser support. Your page should still work without it.
- prefers-reduced-motion should reduce motion, not remove useful feedback from every component on the page.
- Breakpoints are not universal. A design that works well for one layout may need different values for another layout.
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
- @media applies CSS only when a condition matches.
- min-width and max-width are the most common responsive tools.
- prefers-color-scheme supports dark and light appearance preferences.
- prefers-reduced-motion improves accessibility for motion-sensitive users.
- Base styles should work first, and media queries should refine them.
- The cascade still matters, so rule order can change the final result.
11. Practice Exercise
Create a simple page section that responds to three conditions:
- Use one column by default.
- Switch to two columns at 800px or wider.
- Use dark colors when the user prefers dark mode.
- Turn off animation if the user prefers reduced motion.
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.