Media Queries
Media queries let you apply CSS conditionally based on viewport width, screen resolution, or user preferences — the foundation of responsive layouts.
- Write a valid media query using min-width and max-width
- Explain why content should drive breakpoint choice, not device names
- Combine multiple conditions in a single media query
- Use prefers-color-scheme and prefers-reduced-motion to respect user preferences
Once the viewport meta tag is in place, the browser faithfully reports the real screen width to CSS. A media query is how you act on that information — applying a block of styles only when a condition is true.
Basic syntax
A media query wraps a block of CSS rules in a conditional:
@media (min-width: 768px) {
.container {
display: grid;
grid-template-columns: 1fr 2fr;
}
}The rules inside apply only when the viewport is at least 768px wide. Below that width the browser ignores the entire block.
The @media at-rule can test many things — width, height, orientation,
resolution — but min-width and max-width are the ones you will use most.
min-width vs max-width
These two feel similar but encode opposite mental models.
min-width — "start here and add." The base styles apply everywhere; the
media query adds styles for wider viewports. This is the mobile-first approach.
/* Base: one column, always */
.cards {
display: flex;
flex-direction: column;
gap: 1rem;
}
/* Wider than 640px: switch to a row */
@media (min-width: 640px) {
.cards {
flex-direction: row;
}
}max-width — "start here and subtract." The base styles are for wide
screens; the query strips things back for narrow viewports. This is the
desktop-first approach.
/* Base: side-by-side columns */
.cards {
display: flex;
flex-direction: row;
}
/* Narrower than 640px: stack vertically */
@media (max-width: 639px) {
.cards {
flex-direction: column;
}
}Both achieve the same result, but the min-width approach tends to produce
leaner CSS because mobile layouts are usually simpler. You will revisit this
trade-off in depth in the next lesson.
Notice that the max-width example uses 639px while the min-width example
uses 640px. The one-pixel gap prevents both rules firing simultaneously at
exactly 640px — a small but deliberate detail.
Choosing breakpoints
There is no canonical list of correct breakpoints. Common values you will encounter are 480px, 640px, 768px, 1024px, and 1280px, but these were not handed down from the cloud — they were derived from popular device widths at a particular moment in time.
Device widths change every year. A better strategy: add a breakpoint where the content starts to look wrong, not because a device happens to have that width. Resize the browser slowly and watch when the text line-length becomes uncomfortably long, or when whitespace starts looking excessive. That is your breakpoint.
Combining conditions
A media query can require multiple conditions to be true at once:
/* Apply only between 600px and 900px wide */
@media (min-width: 600px) and (max-width: 900px) {
.sidebar {
width: 250px;
}
}
/* Apply when the device is held in portrait orientation */
@media (orientation: portrait) {
.map {
height: 40vh;
}
}The and keyword requires both conditions. You can also separate queries with a
comma, which acts as or:
/* Landscape phone OR wide tablet */
@media (min-width: 480px) and (orientation: landscape),
(min-width: 768px) {
.nav {
flex-direction: row;
}
}Beyond width: user preference queries
Media queries are not only about screen size. Two queries that every site should consider:
prefers-color-scheme
@media (prefers-color-scheme: dark) {
:root {
--bg: #1a1a2e;
--text: #e0e0e0;
}
}When a user has enabled dark mode in their OS settings, this query fires and you can swap your colour tokens. The browser handles the detection — no JavaScript, no cookies.
prefers-reduced-motion
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: 0.01ms !important;
transition-duration: 0.01ms !important;
}
}Some users — those with vestibular disorders, motion sickness, or epilepsy — enable "reduce motion" in their OS accessibility settings. This query catches that preference and disables animations site-wide. It is a one-liner that has a real impact on accessibility.
Omitting prefers-reduced-motion support is an accessibility failure for some
users, not just a missing feature. Add it whenever your design includes
significant motion — parallax scrolling, entrance animations, carousels.
Where to write your media queries
Old pattern: collect all media queries at the bottom of the stylesheet, one large block per breakpoint. This keeps them easy to find but separates a rule from its context — you have to scroll to see the full picture for any selector.
Modern pattern: nest the media query directly inside the selector it modifies. Modern CSS (and all major preprocessors) support this:
.nav {
display: flex;
flex-direction: column;
@media (min-width: 768px) {
flex-direction: row;
}
}The nested form keeps each selector's behaviour self-contained and is easier to read when scanning a component's styles.
Where to go next
You understand how to write media queries. Next: Mobile-First Design — the discipline of writing base styles for the smallest screen and layering complexity upward, and why the discipline produces leaner, more maintainable CSS.
The Viewport
The viewport is the visible area of the browser window — and without the viewport meta tag, mobile browsers lie about its width to fake desktop rendering.
Mobile-First Design
Mobile-first means writing base styles for the smallest screen and adding complexity for larger screens — a discipline that produces leaner, more maintainable CSS.