CSS Media Queries Table
| Feature | Matches when | Typical use |
|---|---|---|
(max-width: 767px) | Viewport at or below the width | The mobile-first breakpoint; min-width climbs up instead |
(min-width: 768px) | Viewport at or above | Desktop layering on a mobile base |
(prefers-color-scheme: dark) | OS dark mode on | Dark themes; pair with color-scheme meta |
(prefers-reduced-motion: reduce) | User asked for less motion | Gate decorative animation - accessibility, not style |
(hover: hover) | Device truly supports hover | Touch screens report none - guard hover menus |
(pointer: coarse) | Primary input is a finger | Bigger hit targets on touch-first devices |
print | Print rendering | Hide nav, expand links - @media print block |
(orientation: landscape) | Width greater than height | Tablet game layouts, video pages |
(display-mode: standalone) | Installed PWA window | Adjust chrome once the app is installed |
(resolution: 2dppx) | Retina-class screens | Swap high-DPI assets |
Media queries are how one stylesheet serves many contexts: viewport sizes, color schemes, input types, even whether the user asked for less motion. The table below is the working ten - the features that cover real responsive work - with the field note for each one's typical use and its traps.
Bottom line: the modern pattern is mobile-first. Write the base styles for small screens, then layer (min-width) breakpoints on top as the screen grows - max-width chains start from the biggest site and keep un-doing themselves, which is why they age badly. And width is only half the story now: the prefers-* family makes media queries an accessibility tool, honoring dark mode and reduced-motion as the user preferences they are.
The honest part: hover is the sneakiest feature on the list. A touch screen reports (hover: none), so hover-only navigation is unreachable on most phones regardless of width - pairing (hover: hover) with width breakpoints is how menus serve both worlds. Width, color scheme, motion, input: four different questions, one query syntax.
How to use
- Write base styles without any query - they are the small-screen default; add @media (min-width: ...) layers upward.
- Add the preference queries alongside the width ones: prefers-color-scheme for themes, prefers-reduced-motion for any animation on the page.
- Guard input-dependent behavior with (hover: hover) and (pointer: coarse) instead of assuming a mouse exists.
Frequently asked questions
Should I use min-width or max-width for breakpoints?
min-width, on a mobile-first base. You write the phone layout with no query at all, then each breakpoint adds what bigger screens get - styles only ever accumulate. max-width workflows start from the desktop version and each query strips things back, which produces long override chains where every later rule fights the earlier ones. The breakpoint values themselves matter less than having three or four consistent ones (roughly 640, 768, 1024, 1280).
How do I implement dark mode with media queries?
@media (prefers-color-scheme: dark) wraps the dark variable overrides - define colors as CSS custom properties in :root, then swap their values inside the query. Set the color-scheme meta or property so form controls and scrollbars follow. One honest caveat: users who want dark mode on a light site often toggle it per-site, so offering a manual class toggle alongside the system preference is the complete answer - the media query is the default, not the only input.
What is prefers-reduced-motion and why does it matter?
A media query that reports the user's OS-level request to minimize non-essential motion - triggered by an accessibility setting, because vestibular disorders make large moving elements genuinely nauseating, not merely annoying. The pattern: define animations inside a default state, and wrap or disable them under @media (prefers-reduced-motion: reduce). This is the rare CSS feature where shipping it is a documented health accommodation, and it costs one media query per animation family.
Why does my hover menu fail on phones even though the width query matches?
Because width and input are different dimensions. Touch devices report (hover: none) and (pointer: coarse) - there is no persistent cursor, so :hover styles apply on tap and stick, and hover-only menus never open their second level. The fix is an input query: wrap hover-dependent styles in @media (hover: hover), and provide tap-first alternatives (click to open, first tap shows the menu). Width queries size the layout; hover and pointer queries describe the hands using it.