← All articles

CSS media queries explained, with mobile examples

CSS media queries explained: syntax, min-width vs max-width, the range syntax, features for mobile, dark mode and touch, and common mistakes.

A CSS media query applies a block of styles only when the device or browser meets a condition, such as a minimum viewport width, a landscape orientation or a dark colour scheme. @media (min-width: 48rem) { ... } means “use these rules when the viewport is at least 48rem wide”. Media queries are the part of CSS that lets one page change its layout between phones, tablets and desktops.

Basic syntax

@media (min-width: 768px) {
  .sidebar { display: block; }
}

A media query has three optional parts:

  • a media type: screen, print or all (the default)
  • one or more media features in parentheses, such as (min-width: 768px) or (orientation: landscape)
  • logical operators that combine them: and, , (or), and not
@media screen and (min-width: 768px) and (orientation: landscape) { ... }
@media (max-width: 480px), (orientation: portrait) { ... }
@media not print { ... }

You can also apply a media query to a whole stylesheet: <link rel="stylesheet" href="print.css" media="print">.

min-width vs max-width

min-width means “this wide or wider”; max-width means “this wide or narrower”. The direction you choose decides how you write the rest of your CSS.

  • Mobile first (recommended): base styles target phones, and min-width queries add layout for larger screens. See mobile-first design.
  • Desktop first: base styles target desktop, and max-width queries undo things for smaller screens.
/* Mobile first */
.nav { flex-direction: column; }

@media (min-width: 48rem) {
  .nav { flex-direction: row; }
}

Mixing both directions in one project tends to create overlaps and gaps. Pick one and use the other only for small exceptions.

The modern range syntax

Media Queries Level 4 adds comparison operators, which are easier to read and avoid off-by-one errors:

@media (width >= 48rem) { ... }
@media (40rem <= width < 64rem) { ... }

Range syntax is supported in all current major browsers (Chrome and Edge since version 104, Firefox since 63, Safari since 16.4). If you need to support older Safari versions, keep using min-width and max-width, or let a build tool convert it.

Note that (width < 768px) and (max-width: 767px) are not identical: the first also matches 767.5 px, which can occur on screens with fractional pixel ratios.

Media queries for mobile: common examples

Stack columns on small screens:

.grid { display: grid; gap: 1rem; }

@media (min-width: 40rem) {
  .grid { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 64rem) {
  .grid { grid-template-columns: repeat(4, 1fr); }
}

Smaller spacing on phones:

.section { padding: 2rem 1rem; }

@media (min-width: 64rem) {
  .section { padding: 6rem 2rem; }
}

Landscape phones with little height:

@media (orientation: landscape) and (max-height: 30rem) {
  .site-header { position: static; }
}

The last one is often forgotten. A sticky header that is fine in portrait can take a third of the screen in landscape.

Which widths to use is a separate question, covered in responsive breakpoints.

Media features beyond width

Feature Example Use it for
orientation (orientation: landscape) Layout changes when a phone or tablet rotates
hover (hover: hover) Hover effects only on devices that can hover
pointer (pointer: coarse) Larger targets for touch screens
prefers-color-scheme (prefers-color-scheme: dark) Dark theme
prefers-reduced-motion (prefers-reduced-motion: reduce) Turning off animations
resolution (min-resolution: 2dppx) High-density images in CSS backgrounds
display-mode (display-mode: standalone) Styling an installed web app

The hover and pointer features matter more than they look. A touch laptop or a tablet with a desktop-width layout still has no hover, so guard hover-only menus with @media (hover: hover).

Use rem or em for breakpoints

Media queries in rem or em follow the user’s browser font size setting. If someone raises their default text size from 16 px to 24 px, a 48rem breakpoint moves from 768 px to 1152 px, so the layout switches to a roomier version when text gets larger. Pixel breakpoints ignore that setting. Inside media queries, rem and em both refer to the browser’s initial font size, not the html font size you set in CSS.

Media queries vs container queries

Media queries respond to the viewport. Container queries respond to the size of an element’s container:

.card-wrap { container-type: inline-size; }

@container (min-width: 30rem) {
  .card { display: flex; }
}

Use media queries for page-level layout (columns, navigation) and container queries for components that appear in places of different widths.

Common mistakes

  1. Missing viewport meta tag. Without it, phones report a viewport around 980 px and your mobile media queries never fire. See the viewport meta tag explained.
  2. Overlapping ranges, such as max-width: 768px and min-width: 768px both matching at exactly 768 px.
  3. Writing media queries before the base rule. Later rules with the same specificity win, so the query must come after the rule it overrides.
  4. Testing only by resizing the window. Desktop browsers will not shrink to most phone widths. Use device mode or a mobile view extension that sets the real viewport and user agent, and see how to test responsive design.

Frequently asked questions

What is the media query for mobile phones?

There is no single phone query. Mobile-first CSS treats phones as the default with no query, and adds @media (min-width: 40rem) or similar for larger screens. To target only small screens, use @media (max-width: 39.99rem) or (width < 40rem).

Should media queries use px, em or rem?

rem or em is better for accessibility, because breakpoints then scale with the user’s font size setting. px works but ignores that setting.

Where should I put media queries in my CSS?

Either next to the component they change or grouped at the end of the file. Placing them next to the component is easier to maintain, and the order must still come after the base rules.

View your next website as mobile.

Add the mobile view Chrome extension and open device previews for the tab you are already working in.