Why media queries are needed in CSS
Media queries are CSS rules that apply styles conditionally based on device characteristics like screen width, orientation, or color scheme.
Theory
TL;DR
- Media queries work like a waiter who adjusts the plate size depending on the table: same food, different presentation for different needs.
- Without them, one CSS file forces the same layout on all screens. A three-column grid that looks clean at 1440px becomes unreadable on a 375px phone.
- Use
max-widthfor desktop-first,min-widthfor mobile-first (the preferred approach). - They activate instantly on resize, no JavaScript needed.
Quick example
/* Base: 3-column grid on desktop */
.card-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20px;
}
/* Phone: screen under 600px → single column */
@media (max-width: 600px) {
.card-grid {
grid-template-columns: 1fr; /* cards stack vertically, no horizontal scroll */
}
}Desktop shows 3 cards side by side. On a 375px phone they stack into one column automatically.
Why fixed styles fail
A stylesheet without media queries locks every device into the same layout. The browser picks one rule set and applies it everywhere, screen size irrelevant. Media queries let the browser evaluate the actual viewport at render time and activate only the matching rule blocks. Same stylesheet, different behavior per device.
When to use
- Mobile-first: base mobile styles first, then
@media (min-width: 768px)for wider screens. - Print:
@media print { .no-print { display: none; } }strips navigation from printed pages. - Dark mode:
@media (prefers-color-scheme: dark) { body { background: #000; } }. - Orientation:
@media (orientation: landscape) { video { height: 100vh; } }. - Accessibility:
@media (prefers-reduced-motion: reduce) { * { animation: none; } }.
How the browser handles it
Browsers parse all CSS upfront. At render time, the layout engine (Blink in Chrome, Gecko in Firefox) evaluates each media feature against the current viewport through window.matchMedia(). When the viewport changes, matching rule sets activate instantly. No page reload, no recalculation for elements outside the matched rules.
Common mistakes
Using width instead of min-width or max-width:
/* Wrong: matches exactly 768px and nothing else */
@media (width: 768px) { ... }
/* Right: matches 768px and below */
@media (max-width: 768px) { ... }Desktop-first base with mobile as an afterthought:
/* Wrong: mobile accidentally inherits 3-column base if the override is missing */
.grid { grid-template-columns: repeat(3, 1fr); }
@media (max-width: 768px) { .grid { grid-template-columns: 1fr; } }
/* Right: mobile-first, add complexity for wider screens */
.grid { grid-template-columns: 1fr; }
@media (min-width: 769px) { .grid { grid-template-columns: repeat(3, 1fr); } }Nesting media queries (one of the most common CSS bugs on Stack Overflow):
/* Wrong: browsers ignore the inner query entirely */
@media (max-width: 768px) {
.parent {
@media (max-width: 480px) { .child {} }
}
}
/* Right: flatten both queries */
@media (max-width: 480px) { .child {} }I've watched devs spend an hour on a layout that looked fine on desktop but broke on mobile, only to find they had nested two queries and the inner one was just ignored the whole time.
Real-world usage
- Tailwind CSS: breakpoints like
md:generate@media (min-width: 768px)automatically. - Bootstrap 5: uses
@media (min-width: 576px)for.containerwidth adjustments. - React apps:
@media (max-width: 1024px) { .menu-toggle { display: block; } }for hamburger nav. - Next.js 14: global CSS with media queries for page-level responsive layout.
Follow-up questions
Q: What is the difference between @media (max-width: 768px) and viewport units like vw?
A: max-width switches entire rule sets at a specific breakpoint. vw scales a single property continuously, like font-size: 5vw. Media queries give discrete layout changes; viewport units give gradual scaling.
Q: How does dark mode work with CSS?
A: @media (prefers-color-scheme: dark) { body { background: #000; color: #fff; } }. The browser reads the OS setting and applies the styles automatically, no JavaScript needed.
Q: What are container queries and how do they differ from media queries?
A: Media queries respond to the viewport size. Container queries (@container) respond to the size of a parent element, which makes components reusable regardless of placement. Supported in Chrome 105+ and Firefox 110+.
Q: How do you debug a media query not applying on iOS Safari?
A: Check for the viewport meta tag first: <meta name="viewport" content="width=device-width, initial-scale=1">. Without it, iOS renders at desktop scale and pixel-based breakpoints behave unpredictably. Also verify any -webkit- prefixed features you are using.
Examples
Basic: padding adjustment by screen size
.hero {
padding: 100px 40px; /* desktop: generous spacing */
}
@media (max-width: 768px) {
.hero {
padding: 20px 10px; /* mobile: compact */
}
}On a 1920px monitor you get 100px top/bottom padding. On a 375px iPhone it drops to 20px. Same element, two behaviors, zero JavaScript.
Navigation collapse for tablet and mobile
.nav-bar {
display: flex;
justify-content: space-between; /* horizontal on desktop */
}
.menu-toggle {
display: none; /* hamburger hidden on desktop */
}
@media (max-width: 1024px) {
.nav-bar {
flex-direction: column; /* stacks vertically for smaller screens */
}
.menu-toggle {
display: block; /* hamburger icon appears */
}
}This pattern shows up in every production app with a responsive nav, from GitHub to Vercel's dashboard. The toggle button only appears when the screen is too narrow for a horizontal bar. CSS handles the entire layout change.
Short Answer
Interview readyA concise answer to help you respond confidently on this topic during an interview.