skip to content

In a CSS media query, how does the range syntax such as @media (width >= 40rem) differ from @media (min-width: 40rem), and what problem does it solve?

level: middleimportance: should knowfreq 45%

answer

  1. same match, better spelling
  2. min- and max- are always inclusive
  3. that is where 767.98px comes from
  4. strict operators partition exactly
  5. ordered features only

basics

~20 s

They match identically, but the range syntax adds strict comparisons. min-width and max-width are always inclusive, so complementary breakpoints overlap by one pixel; range syntax writes width >= 40rem and width < 40rem, which partition the axis exactly, and supports two-sided ranges in one query.

solid answer

~50 s

`@media (width >= 40rem)` and `@media (min-width: 40rem)` mean exactly the same thing — the range syntax from Media Queries Level 4 is a more readable spelling of the same comparison. What it *adds* is the strict operators. The `min-`/`max-` prefixes are inclusive only, so a pair like `max-width: 40rem` and `min-width: 40rem` both match at exactly 40rem, which is why people write `40rem` and `39.99rem` and why fractional viewport widths from zoom or non-integer device pixel ratios can fall into an unstyled gap. With range syntax you write `(width < 40rem)` and `(width >= 40rem)` and the two are exact complements. You can also express a band in one query: `@media (30rem <= width < 60rem)`. It only applies to range-type features — `width`, `height`, `aspect-ratio`, `resolution` — never to discrete ones like `orientation` or `hover`, and it has been supported across all the major browsers since 2023.

code

css · 13 lines
css
.card { display: block; }

@media (width >= 48rem) {
  .card { display: flex; gap: 1rem; }
}

@media (30rem <= width < 48rem) {
  .card { padding-inline: 2rem; }
}

@media (resolution >= 2dppx) {
  .logo { background-image: url("[email protected]"); }
}

go deeper

for a junior

Know that (width >= 40rem) is just another way to write (min-width: 40rem), and be able to read both spellings in a stylesheet without hesitating over which direction each one bounds.

for a middle

Explain that min-/max- are inclusive on both ends, show the overlap that creates at the shared breakpoint, and write the exact-complement pair with < and >= instead.

for a senior

Bring the production angle: fractional viewport widths from zoom and display scaling, why framework decimals exist, that an invalid range query silently drops a whole block, and how tooling down-compiles for older targets.

for a principal

Own the house convention — one spelling across the codebase, one direction of cascade, breakpoints as named tokens rather than literals — and the migration cost of changing it once hundreds of components depend on the current set.

## Two spellings of one comparison Media Queries Level 4 added a comparison syntax for features that have an ordered range of values. These pairs are equivalent: ```css @media (min-width: 40rem) { } @media (width >= 40rem) { } @media (max-height: 30rem) { } @media (height <= 30rem) { } ``` Nothing about matching changes. The `min-`/`max-` prefixed forms are not deprecated and continue to work. What you gain is readability — `width >= 40rem` reads as the comparison it is, whereas `min-width` is a small puzzle every time, because it describes the *minimum the viewport must have* rather than a maximum bound on the rule. ## The inclusivity problem The substantive difference is that `min-` and `max-` are *always inclusive*: `min-width: 40rem` means width ≥ 40rem and `max-width: 40rem` means width ≤ 40rem. Write the obvious complementary pair and both match at exactly 40rem: ```css @media (max-width: 40rem) { .card { display: block; } } @media (min-width: 40rem) { .card { display: flex; } } ``` At precisely 40rem, both blocks apply and the later one silently wins. The historical workaround is to back one bound off by a hair — `max-width: 767.98px` next to `min-width: 768px` — which most component libraries still ship. The `.98` is not superstition: viewport widths are not necessarily integers. Page zoom, an OS display scale factor, and fractional device pixel ratios all produce widths like `767.5px`, and a `767px`/`768px` pair leaves those widths matching *neither* rule, producing a narrow band where the element is unstyled. Range syntax removes the whole class of problem, because it has strict operators: ```css @media (width < 48rem) { .card { display: block; } } @media (width >= 48rem) { .card { display: flex; } } ``` Every real number is in exactly one of those two sets. No overlap, no gap, no magic decimal. ## Two-sided ranges The syntax also allows a bound on both sides in a single query, with the feature name in the middle: ```css @media (30rem <= width < 60rem) { } ``` The pre-Level-4 spelling needs two conditions joined with `and`, plus the same off-by-a-hair care: `@media (min-width: 30rem) and (max-width: 59.99rem)`. ## Which features accept it Only *range-type* features — ones whose values are ordered. In practice: `width`, `height`, `inline-size`, `block-size`, `aspect-ratio`, `resolution`, `color`, `color-index`, `monochrome`. Discrete features have no ordering, so `@media (orientation >= landscape)` or `@media (hover >= hover)` are simply invalid, and an invalid query never matches — the whole block is dropped silently, which is a nasty way to lose a rule. `resolution` is worth remembering as a range feature, since it is the modern way to target high-density displays: `@media (resolution >= 2dppx)`. The old `-webkit-min-device-pixel-ratio` you still see in legacy stylesheets is a vendor-prefixed relic of the same idea. ## Units inside a media query A detail that surprises people: relative units in a media query resolve against the *initial* value of `font-size`, not against whatever the page set on the root element. So if a stylesheet does `html { font-size: 62.5%; }` to make `1rem` equal `10px` in the document, the breakpoints do **not** shift — `40rem` in the query is still 40 × the browser's default font size, typically 640px. It does, however, track the *user's* browser font-size preference, which is precisely why em/rem breakpoints are preferred over px ones: a user who raises their default text size gets the smaller-viewport layout at a proportionally larger viewport, which is usually the layout they need. ## Support and fallbacks Range syntax reached all the major engines in 2022–2023 (Firefox 102, Chrome 104, Safari 16.4) and is Baseline since then. Older browsers do not understand the query, treat it as invalid, and skip the entire block — a hard failure, not a graceful one. That is a non-issue for most projects today, and where it is not, build tooling such as Lightning CSS or PostCSS can down-compile range queries to the `min-`/`max-` forms automatically.

  • Why do so many CSS frameworks write max-width: 767.98px instead of 767px?
    Because `max-width` is inclusive and viewport widths need not be integers. Pairing `767px` with `min-width: 768px` leaves widths like 767.5px — produced by page zoom or a fractional device pixel ratio — matching neither query, so the element falls back to unstyled defaults in a narrow band. The `.98` closes the gap while still excluding 768px. Range syntax with `<` and `>=` removes the need for the trick.
  • What happens if you write @media (orientation >= landscape)?
    It is an invalid media query, so it never matches and the entire block is dropped without an error in the page. Range syntax applies only to features with ordered values — `width`, `height`, `aspect-ratio`, `resolution` and friends. `orientation` is discrete: its values are `portrait` and `landscape`, which have no ordering, so it must be tested with the plain `(orientation: landscape)` form.
  • If a stylesheet sets html { font-size: 62.5% }, do rem-based breakpoints move?
    No. Relative units inside a media query resolve against the initial font-size, not the root element's computed value, so `@media (width >= 40rem)` stays at 40 × the browser default — typically 640px. It does follow the user's own default-font-size preference, which is the real argument for rem breakpoints over px: users who enlarge text get the narrower-viewport layout sooner.

saying these in an interview costs you the question

  • Thinks min-width is exclusive at the boundary value
  • Believes range syntax changes which widths match
  • Uses >= with orientation, hover, or prefers-color-scheme
  • Assumes viewport width is always an integer number of pixels
  • Says rem breakpoints follow the html element's font-size

context