ποΈ Media Queries and Breakpoints
If responsive design is the philosophy, media queries are the switchgear. They let one stylesheet ask questions about the device β how wide is the viewport? is this a touchscreen? does the user prefer dark mode? β and apply different rules based on the answers. This lesson turns that switch on.
π― Learning Objectives
By the end of this lesson, you will be able to:
- Write a valid media query and explain each part of its syntax
- Use the most common media features β width, orientation, pointer, and user-preference queries
- Choose breakpoints driven by content rather than by specific device sizes
- Apply the mobile-first (
min-width) pattern and know whenmax-widthis appropriate - Recognize container queries and
@supports, and debug active breakpoints in DevTools
Estimated Time: 30β40 minutes β’ Difficulty: BeginnerβIntermediate
Hands-on: Build a three-section layout that reflows across mobile, tablet, and desktop breakpoints.
In This Lesson
What Media Queries Do
A media query is a conditional wrapper around a block of CSS. It reads, in plain English: "If the device matches these conditions, apply these rules." Everything outside the query is the baseline that always applies; the query only adds or overrides rules when its condition is true.
π Key Terms
Media feature: the device characteristic being tested β e.g. width, orientation, pointer.
Breakpoint: a specific viewport width where you switch layouts.
Viewport meta tag: the <meta name="viewport"> line that tells mobile browsers to use the real device width β without it, media queries fire against a faked desktop width.
Syntax & Features
A media query is built from an optional media type, one or more feature tests joined by logical operators, and a block of CSS.
@media screen and (min-width: 768px) {
/* Applies to screens 768px wide and up */
.container { max-width: 750px; }
}
Common media types
allβ every media type (the default if you omit it)screenβ monitors, tablets, phonesprintβ printers and print preview
Common media features
| Feature | Tests for |
|---|---|
min-width / max-width | Viewport width thresholds β by far the most used |
orientation | portrait or landscape |
aspect-ratio | Width-to-height ratio of the viewport |
resolution | Pixel density, for targeting high-DPI (Retina) screens |
hover | Whether the device can hover (hover / none) |
pointer | Pointer precision: fine (mouse) or coarse (touch) |
prefers-color-scheme | User's light/dark preference |
prefers-reduced-motion | Whether the user asked to minimize animation |
β Modern range syntax
Current browsers support comparison operators, which read more naturally than min-/max- pairs:
/* Old */
@media (min-width: 768px) and (max-width: 1023px) { ... }
/* New range syntax β same meaning, clearer intent */
@media (768px <= width < 1024px) { ... }
Worked Examples
Width-based adaptation
/* Base (mobile) styles apply everywhere first */
.sidebar { display: none; }
/* On wider screens, reveal the sidebar */
@media (min-width: 768px) {
.sidebar { display: block; width: 25%; }
.content { width: 75%; }
}
Adapting to input type
Touch users need bigger tap targets than mouse users. The pointer feature lets you serve each appropriately.
/* Precise pointer (mouse): compact controls are fine */
@media (pointer: fine) {
.button { padding: 6px 12px; }
}
/* Coarse pointer (touch): enlarge to a comfortable tap target */
@media (pointer: coarse) {
.button { padding: 14px 22px; } /* ~44px tall */
}
Print styles
@media print {
nav, footer, .comments { display: none; } /* strip screen-only chrome */
body { font-size: 12pt; color: #000; }
a[href]::after { content: " (" attr(href) ")"; } /* show URLs on paper */
}
π‘ The viewport meta tag is not optional
Every responsive page needs this in its <head>, or mobile browsers render at a ~980px virtual width and shrink the result β defeating your queries entirely:
<meta name="viewport" content="width=device-width, initial-scale=1.0">
Choosing Breakpoints
A breakpoint is simply the width where you decide the layout should change. There are two schools of thought about where to put them.
The content-based approach wins: start from your base design, slowly widen the browser, and add a breakpoint at each point where the layout starts to look stretched, cramped, or awkward. Your breakpoints then belong to your content, not to a device catalog that changes every year.
π‘ A pragmatic default set
Frameworks like Bootstrap 5 offer sensible starting thresholds β ~576px, 768px, 992px, 1200px, 1400px β but treat them as a starting grid, then adjust to your content.
Common Patterns
Mobile-first (min-width) β the default
Write the simplest mobile layout as the base, then layer enhancements upward. This keeps the base lightweight and is the pattern we recommend throughout this course.
/* Base: stacked navigation on small screens */
.navigation { display: flex; flex-direction: column; }
/* Enhancement: go horizontal on larger screens */
@media (min-width: 768px) {
.navigation { flex-direction: row; }
}
Desktop-first (max-width) β use sparingly
/* Base: full desktop layout */
.navigation { display: flex; flex-direction: row; }
/* Override downward for small screens */
@media (max-width: 767px) {
.navigation { flex-direction: column; }
}
Multi-column to single-column grid
.grid { display: grid; grid-template-columns: 1fr; } /* mobile: 1 col */
@media (min-width: 768px) { .grid { grid-template-columns: 1fr 1fr; } } /* tablet: 2 */
@media (min-width: 992px) { .grid { grid-template-columns: 1fr 1fr 1fr; } } /* desktop: 3 */
β οΈ Don't over-fragment
Too many breakpoints make CSS brittle and hard to reason about. Prefer intrinsically fluid layouts (Flexbox, Grid auto-fit) and add a query only where fluidity alone can't express the change.
Modern Queries
Container queries
A media query asks about the viewport. A container query asks about a component's own parent β so a card can lay itself out differently in a narrow sidebar than in a wide main column, on the same page. This is now supported across all evergreen browsers.
.card-wrapper { container-type: inline-size; }
/* When the WRAPPER (not the screen) is at least 400px wide */
@container (min-width: 400px) {
.card { display: grid; grid-template-columns: auto 1fr; }
}
Feature queries with @supports
Media queries test the device; @supports tests the browser's CSS capabilities, so you can progressively enhance without breaking older engines.
.layout { display: block; } /* safe fallback */
@supports (display: grid) {
.layout {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
}
}
User-preference queries
@media (prefers-color-scheme: dark) {
body { background: #121212; color: #f0f0f0; }
}
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms !important;
transition-duration: 0.01ms !important;
}
}
Debugging
Browser DevTools make breakpoints visible. In the device toolbar (Ctrl/Cmd + Shift + M), a ruler across the top shows your defined breakpoints as clickable segments, and the Styles pane highlights which @media block is currently active.
For quick visual confirmation during development, a temporary label that changes per breakpoint tells you at a glance which query is live:
body::before {
content: "mobile";
position: fixed; top: 0; right: 0; z-index: 9999;
padding: 4px 8px; background: crimson; color: #fff; font: 12px monospace;
}
@media (min-width: 768px) { body::before { content: "tablet"; background: royalblue; } }
@media (min-width: 992px) { body::before { content: "desktop"; background: seagreen; } }
β οΈ Remove debug helpers before shipping
The label above is a development aid only. Strip it (or guard it behind a dev-only class) before deploying.
Hands-on Exercise
ποΈ Build a Reflowing Layout
Objective: Write mobile-first media queries that reflow a page across three breakpoints.
Instructions:
- Create a page with a header (logo + nav), a main area holding three content cards, a sidebar, and a footer.
- Write the base CSS for mobile: everything stacks in a single column; the nav is hidden behind a toggle.
- Add
@media (min-width: 768px): cards become a two-column grid and the nav goes horizontal. - Add
@media (min-width: 992px): cards become three columns and the sidebar sits beside the main content. - Add one non-width query β either a
@media printblock or aprefers-reduced-motionblock.
π‘ Hint
Lay the main + sidebar out with display: grid on a wrapper. At the desktop breakpoint, switch grid-template-columns from 1fr to something like 3fr 1fr. Keep every query min-width so each one only adds to the mobile base.
β Sample solution
/* Base: mobile, single column */
.layout { display: grid; grid-template-columns: 1fr; gap: 1rem; }
.cards { display: grid; grid-template-columns: 1fr; gap: 1rem; }
.nav-menu { display: none; }
.nav-toggle { display: block; }
/* Tablet */
@media (min-width: 768px) {
.cards { grid-template-columns: 1fr 1fr; }
.nav-menu { display: flex; }
.nav-toggle { display: none; }
}
/* Desktop */
@media (min-width: 992px) {
.cards { grid-template-columns: 1fr 1fr 1fr; }
.layout { grid-template-columns: 3fr 1fr; } /* main | sidebar */
}
/* Non-width query */
@media (prefers-reduced-motion: reduce) {
* { transition: none !important; animation: none !important; }
}
π― Quick Quiz
Question 1: In a mobile-first stylesheet, which query type layers enhancements on top of the base styles?
Question 2: What distinguishes a container query from a media query?
Question 3: Why should breakpoints usually be content-based rather than tied to specific device widths?
Summary & Quiz
π Key Takeaways
- A media query wraps CSS in a condition and applies it only when the condition is true.
- Beyond width, you can test orientation, pointer, resolution, and user preferences.
- Prefer content-based breakpoints and the mobile-first
min-widthpattern. - Container queries and
@supportsextend responsiveness to components and browser capabilities. - Always ship the viewport meta tag; use DevTools to watch active breakpoints.
π Further Reading
π What's Next?
You now control when styles change. Next we make the mobile-first idea a deliberate strategy β starting from the smallest screen and progressively enhancing, with the performance and content-prioritization habits that come with it.
π Great work!
Media queries are the throttle of responsive design. Next, let's decide which direction to drive.