How do media queries work?
Breakpoints, min-width, mobile-first.
A media query applies CSS only when a condition is true — usually a viewport width. Write base styles for the smallest screen, then add rules for larger screens with min-width. That's mobile-first CSS, and it's the modern default. This page covers the syntax, the breakpoints that matter, and the difference between min-width and max-width.
Short answer: Use @media (min-width: 768px) {'{ ... }'} for mobile-first. Write base CSS for mobile, then add rules at each breakpoint. Common breakpoints: 640px, 768px, 1024px, 1280px, 1536px. Pick breakpoints where your design breaks, not where devices happen to be. Use max-width only if you're maintaining a desktop-first codebase. Prefer min-width for new projects — it's easier to reason about and produces smaller CSS.
✅ The two directions
min-width or max-width. Pick one per project.
min-width — mobile-first
Matches viewports at least this wide. Base styles are mobile. Add rules as the screen grows. Preferred.
max-width — desktop-first
Matches viewports at most this wide. Base styles are desktop. Override as the screen shrinks. Older pattern.
Why mobile-first wins
Smaller CSS (mobile users don't download desktop rules). Logical progression (add complexity, don't override). Easier to test (start with the hardest constraint).
Combining conditions
@media (min-width: 768px) and (max-width: 1023px) — matches only a specific range. Useful for "tablet-only" rules.
✅ Before and after
Mobile-first CSS in practice.
/* Base styles — mobile */
.grid {
display: grid;
grid-template-columns: 1fr;
gap: 1rem;
padding: 1rem;
}
.title {
font-size: 1.5rem;
}
/* Tablet — 768px and up */
@media (min-width: 768px) {
.grid {
grid-template-columns: 1fr 1fr;
padding: 2rem;
}
.title {
font-size: 2rem;
}
}
/* Desktop — 1024px and up /
@media (min-width: 1024px) {
.grid {
grid-template-columns: repeat(3, 1fr);
}
.title {
font-size: 2.5rem;
}
}
Rendered layout: Mobile (0–767px): ┌──────┐ │ Card │ ├──────┤ │ Card │ ├──────┤ │ Card │ └──────┘ font-size: 1.5rem Tablet (768–1023px): ┌──────┬──────┐ │ Card │ Card │ ├──────┼──────┤ │ Card │ │ └──────┴──────┘ font-size: 2rem Desktop (1024px+): ┌──────┬──────┬──────┐ │ Card │ Card │ Card │ └──────┴──────┴──────┘ font-size: 2.5rem ✅ Base styles apply everywhere. ✅ Each min-width adds more columns. ✅ No "undo" rules — the CSS only grows. ✅ Smaller payload for mobile users.
/* Base styles — desktop */
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 1rem;
padding: 2rem;
}
.title {
font-size: 2.5rem;
}
/* Tablet and below */
@media (max-width: 1023px) {
.grid {
grid-template-columns: 1fr 1fr;
padding: 2rem;
}
.title {
font-size: 2rem;
}
}
/* Mobile and below /
@media (max-width: 767px) {
.grid {
grid-template-columns: 1fr;
padding: 1rem;
}
.title {
font-size: 1.5rem;
}
}
Same visual result as mobile-first. ⚠️ Differences: ❌ Base CSS is desktop — mobile users download desktop rules they'll never use, then download overrides. Larger total payload. ❌ Mental model is "start big, undo." You have to remember what the base rules were, then what each max-width undoes. ❌ Cascade order matters — the last max-width wins, so you must order breakpoints from largest to smallest. Easy to get wrong. ✅ Mobile-first avoids all three problems. Use min-width for new code.
✅ The standard breakpoints
Conventions, not rules. Pick where your design breaks.
/* Base — mobile /
/ Everything above 0px */
@media (min-width: 640px) { /* sm / }
@media (min-width: 768px) { / md / }
@media (min-width: 1024px) { / lg / }
@media (min-width: 1280px) { / xl / }
@media (min-width: 1536px) { / 2xl / }
These are Tailwind's defaults. They work for most sites. But they're not rules — they're conventions. 640px → small tablet / large phone landscape 768px → tablet portrait 1024px → tablet landscape / small desktop 1280px → desktop 1536px → large desktop Better approach: pick breakpoints where YOUR design breaks. If your card grid looks cramped at 900px, that's your breakpoint. Not 768px because an iPhone happens to be 390px wide. Design-driven > device-driven. Modern alternative: use container queries (@container) for components, and media queries only for page-level layout.
Don't use device-specific breakpoints. @media (max-width: 375px) for "iPhone" is a common mistake. Devices change every year — the iPhone 15 is 393px wide, the iPhone 16 Pro Max is 440px. There is no stable "iPhone width." Use design-driven breakpoints: the point at which your layout starts to break, regardless of what device happens to be that wide. The result is CSS that works on every device, present and future, without updates.
⚠️ Common mistakes
The media-query mistakes that cost real time.
Confusing override order. Fix: pick one direction per project. Mobile-first (min-width) preferred.
"iPhone" and "iPad" widths change. Fix: break at design points, not device widths.
Media queries don't fire without it. Fix: add .
One rule per breakpoint, 8 breakpoints — unmaintainable. Fix: 3–5 breakpoints usually enough.
max-width with mobile-first baseDouble override. Fix: min-width with mobile-first.
only screen for print@media print overrides screen rules if not careful. Fix: @media only screen and (...) when needed.
Real devices have different behavior (iOS Safari, Android Chrome). Fix: test on actual phones.
@media (prefers-reduced-motion: reduce) disables animations for users who need it. Fix: add it.
❓ Frequently asked
How do CSS media queries work?
A media query applies CSS only when a condition is true. Syntax: @media (min-width: 768px) { ... } — the rules inside only apply when the viewport is 768px or wider. Media queries are the foundation of responsive design: write base styles for the smallest screen, then add rules for larger screens with min-width. You can combine conditions with and: @media (min-width: 768px) and (max-width: 1023px).
What is the difference between min-width and max-width in media queries?
min-width: 768px matches viewports 768px and wider — used in mobile-first CSS. max-width: 767px matches viewports 767px and narrower — used in desktop-first CSS. Modern best practice is mobile-first with min-width. It's easier to reason about and results in smaller CSS.
What are the standard breakpoints?
There are no official breakpoints in CSS — you pick based on your content. Common conventions: 640px, 768px, 1024px, 1280px, 1536px. These match Tailwind CSS defaults. The important rule: pick breakpoints where your design breaks, not where devices happen to be.
What is mobile-first CSS?
Write your base CSS for the smallest screen, then add media queries with min-width for larger screens. The base styles apply everywhere; each media query adds complexity as the viewport grows. This is the modern default because most traffic is mobile, mobile is the hardest constraint, CSS grows logically, and the payload is smaller.
Can I use media queries for print styles?
Yes — @media print { ... } applies only when the page is printed. Use it to hide navigation, expand links to show their URL, remove background colors, and use serif fonts. Print stylesheets are a real accessibility feature. Most sites don't bother, but adding a minimal print stylesheet is a quick win.
What are container queries?
Container queries are a newer CSS feature that applies rules based on the size of a parent container, not the viewport. Syntax: @container (min-width: 400px) { ... }. This lets a card respond to its own width, not the screen's. Container queries are supported in all modern browsers since 2023.