CSS Media Queries, Tested Live on Your Device

A media query applies CSS only when a condition about the device or the user's settings is true. @media (width >= 48rem) { ... } targets wider screens; prefers-color-scheme, prefers-reduced-motion, hover and pointer describe settings and input. Write the small-screen styles first, then add min-width queries for larger layouts.

Most used queries
GoalQuery
Tablet and up@media (width >= 48rem)
Phones only@media (width < 40rem)
Dark mode@media (prefers-color-scheme: dark)
Less animation@media (prefers-reduced-motion: reduce)
Mouse users@media (hover: hover) and (pointer: fine)
Printing@media print

Updated

The panel below runs sixteen queries through window.matchMedia on your own browser and updates as you resize the window, rotate a phone or switch dark mode. Under it: the range syntax, user preference queries, input queries, framework breakpoints, and when a container query is the better tool.

Queries tested by the live panel

Each query and what a match means
GroupQueryMatches when
Width(width < 40rem)Narrower than Tailwind sm (640px at default font size)
Width(40rem <= width < 64rem)Between Tailwind sm and lg
Width(width >= 64rem)Tailwind lg and up
Width(min-width: 768px)Classic tablet breakpoint, old syntax
Orientation(orientation: portrait)Viewport taller than wide
Orientation(orientation: landscape)Viewport wider than tall
Input(hover: hover)Main input can hover (mouse, trackpad)
Input(pointer: coarse)Main input is imprecise (finger)
Input(pointer: fine)Main input is precise (mouse, stylus)
Input(any-hover: hover)At least one input can hover
Preference(prefers-color-scheme: dark)System set to dark mode
Preference(prefers-reduced-motion: reduce)User asked for less motion
Preference(prefers-contrast: more)User asked for more contrast
Display(min-resolution: 2dppx)High density screen, 2x or more
Display(display-mode: standalone)Running as an installed web app
DisplayprintPrinting or print preview

Common breakpoint sets

Values from the official Tailwind CSS v4 and Bootstrap 5 documentation. Tailwind's are in rem, shown here at the default 16px.

Default breakpoints in two popular frameworks (min-width, mobile first)
NameTailwind v4Bootstrap 5
sm40rem (640px)576px
md48rem (768px)768px
lg64rem (1024px)992px
xl80rem (1280px)1200px
2xl / xxl96rem (1536px)1400px

Range syntax and the classic form

Same breakpoints, two syntaxes

Range syntax reads like maths and makes non-overlapping bands easy: < on one side, >= on the other.

/* classic */
@media (min-width: 768px) and (max-width: 1023.98px) { .nav { gap: 1rem; } }

/* range syntax */
@media (768px <= width < 1024px) { .nav { gap: 1rem; } }

/* mobile first: base, then larger */
.grid { display: grid; gap: 1rem; }
@media (width >= 48rem) { .grid { grid-template-columns: 1fr 1fr; } }
@media (width >= 80rem) { .grid { grid-template-columns: repeat(4, 1fr); } }

Preferences and input

Small additions that make a site feel native on every device.

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; scroll-behavior: auto !important; }
}
@media (hover: hover) and (pointer: fine) {
  .card:hover { transform: translateY(-2px); }
}
@media (pointer: coarse) {
  .icon-button { min-width: 44px; min-height: 44px; }
}
@media print {
  nav, .ads { display: none; }
}

The same queries in JavaScript

matchMedia returns an object with matches and a change event. This is what the live panel on this page uses.

const dark = window.matchMedia("(prefers-color-scheme: dark)");
console.log(dark.matches);
dark.addEventListener("change", (e) => {
  document.documentElement.dataset.theme = e.matches ? "dark" : "light";
});

Media query or container query?

Choosing between them
Media queryContainer query
Looks atViewport, device, user settingsSize or style of a parent container
SetupNonecontainer-type: inline-size on the parent
Syntax@media (width >= 48rem)@container (width >= 30rem)
Best forPage layout, preferences, printReusable components placed in columns of any width
Tailwind v4md:flex@container on the parent, @md:flex on the child

A card that reacts to its own width

Both cards have the same markup. Only the wide one has room to switch to a row layout. Edit the widths to see it change.

<style>
  .wrap { container-type: inline-size; border: 1px dashed #94a3b8; margin-bottom: 8px }
  .card { display: grid; gap: 8px; padding: 10px; font: 14px system-ui }
  .card div { background: #bfdbfe; height: 40px; border-radius: 6px }
  @container (width >= 320px) { .card { grid-template-columns: 100px 1fr } }
</style>
<div class="wrap" style="width: 220px"><div class="card"><div></div><p style="margin:0">Narrow container</p></div></div>
<div class="wrap" style="width: 400px; max-width: 100%"><div class="card"><div></div><p style="margin:0">Wide container</p></div></div>

Tailwind mapping

Tailwind v4 variants and the CSS they produce
VariantCSS
md:@media (width >= 48rem)
max-md:@media (width < 48rem)
md:max-xl:48rem and up, below 80rem
min-[900px]:@media (width >= 900px)
dark:@media (prefers-color-scheme: dark) by default
motion-reduce:@media (prefers-reduced-motion: reduce)
portrait: / landscape:@media (orientation: portrait) / (orientation: landscape)
print:@media print

Anatomy of a media query

A query is an optional media type (screen, print or all) followed by feature tests in parentheses. @media screen and (orientation: landscape) needs both to be true. A comma between queries means either one is enough.

Queries do not add specificity. The rule inside wins or loses by normal cascade order, which is why responsive overrides usually go after the base styles in the file.

Input and preference queries

hover and pointer describe the primary input; any-hover and any-pointer describe all of them. A laptop with a touch screen typically reports hover: hover and pointer: fine for its trackpad, while any-pointer: coarse is also true because of the screen.

Preference queries reflect choices the person made in their system settings. Honouring prefers-reduced-motion is an accessibility requirement in practice, and prefers-color-scheme lets the site match the rest of their screen.

How it works

  1. Look at the live panel: green rows match on this device right now.
  2. Resize the window, rotate your device or switch your system theme. The rows update on their own.
  3. Copy the queries you need from the reference sections.
  4. For exact screen and viewport sizes, open the screen resolution tool.

Tips

Frequently asked questions

What is the media query range syntax?

A shorter way to write width conditions with comparison operators: (width >= 600px) instead of (min-width: 600px), and (400px <= width < 900px) for a band. It is supported in all current major browsers; Safari added it in 16.4 in 2023, so check caniuse if you support older devices.

Is min-width or max-width better?

Mobile-first stylesheets use min-width: base styles serve small screens and each query adds layout for wider ones. That keeps small-screen CSS simple. max-width is fine for small exceptions, but mixing both at the same breakpoint can leave a one-pixel gap or overlap; range syntax with < and >= avoids that.

How do I detect dark mode in CSS?

Use @media (prefers-color-scheme: dark) and redefine your colour variables inside it. In JavaScript, window.matchMedia('(prefers-color-scheme: dark)').matches gives the same answer, and its change event fires when the user switches.

What is the difference between media queries and container queries?

Media queries look at the viewport and the device. Container queries look at the size of a parent element marked with container-type. A card that should change layout when its column is narrow, wherever it is placed, wants a container query.

Why is my media query not working?

Common causes: the viewport meta tag is missing, so phones pretend to be about 980px wide; the query sits above the rule it should override and loses on source order; or there is a missing space or parenthesis, which silently invalidates the whole condition.

Related: Screen resolution and viewport tool, CSS variables, Modern CSS features, Flexbox and grid cheat sheet, Scroll animations.

Start for free or see all free tools. We.Inc is free to start, with no card needed. AI building is on paid plans from $20 a month.

More in Guides

We.Inc is an AI-powered website builder you can resell under your own brand. Launch a branded client dashboard, bill on Stripe Connect, and deliver AI-generated websites in minutes. White-label plans start at $99 a month for 25 client sites, with a 7-day free trial and no per-site fees.

Product

Who It's For

Features

Resources

Company

View Sitemap