In CSS, how do you express AND, OR, and NOT across @media conditions, and what does the leading only keyword do?
answer
- comma is the union, not the intersection
- type defaults to all when omitted
- not swallows the whole query
- only is a fossil for IE 8
- invalid queries just never match
basics
~20 sAND is the and keyword between parenthesised conditions. OR is a comma-separated list of whole queries, with an explicit or keyword available in newer syntax. NOT negates an entire query. The legacy only keyword hides a query from pre-Level-3 browsers and otherwise does nothing.
solid answer
~50 s`and` joins conditions that must all hold: `@media screen and (width >= 40rem) and (orientation: landscape)`. OR is traditionally the comma — `@media print, (width < 30rem)` applies when *either* query matches, and the comma separates whole queries, not features. Media Queries Level 4 also added an explicit `or` keyword between parenthesised conditions, though you cannot freely mix `and` and `or` at the same level without parentheses. `not` negates an entire query, so in a comma list it only negates the query it appears in; Level 4 also allows negating a single condition, as in `@media (not (hover: hover))`. Finally, `only` is a compatibility relic: `@media only screen and (…)` made browsers that understood media types but not media features skip the rule. Modern browsers ignore it, and it must be followed by a media type.
code
css · 14 lines/* AND: every condition must hold */
@media screen and (width >= 40rem) and (orientation: landscape) {
.layout { grid-template-columns: 16rem 1fr; }
}
/* OR: a comma-separated list matches if any member matches */
@media print, (width < 30rem) {
.sidebar { display: none; }
}
/* NOT applied to a single condition */
@media (not (hover: hover)) {
.tooltip { display: none; }
}go deeper
Be able to read a query aloud correctly: and means every condition must hold, and a comma means any one of the listed queries is enough. Know that omitting the media type means all.
Explain that not applies to the entire query rather than the following condition, that the comma separates whole queries and not features, and what only was originally for.
Show judgment about which conditions belong in a query at all — capability and dimension rather than device guesses — and why an invalid query failing silently is a debugging trap worth checking first.
Own the codebase's query vocabulary: a small named set of conditions rather than ad-hoc combinations scattered through components, so that a breakpoint or capability policy can be changed in one place.
## The anatomy of a query An `@media` rule takes a comma-separated *list* of media queries. Each query is an optional media type (`all`, `print`, `screen`, `speech`) plus zero or more *conditions* in parentheses, joined by logical keywords. If the media type is omitted it defaults to `all`, which is why `@media (width >= 40rem)` and `@media all and (width >= 40rem)` behave identically. ```css @media screen and (width >= 40rem) { } /* ^type ^join ^condition */ ``` When a media type appears, `and` is required between it and the first condition. `@media screen (width >= 40rem)` is invalid. ## AND `and` between parenthesised conditions requires all of them: ```css @media (width >= 40rem) and (orientation: landscape) and (hover: hover) { } ``` There is no limit on how many you chain, and the browser short-circuits nothing you can observe — either the whole conjunction matches or the block does not apply. ## OR — the comma CSS has no `or` in the original Level 3 syntax. The comma plays that role, and it separates *entire queries*, not conditions: ```css @media print, (width < 30rem) { .sidebar { display: none; } } ``` This applies when printing **or** when the viewport is narrow. A very common misreading treats the comma as "and", producing rules that fire far more often than intended. The mental model to hold: a comma-separated list matches if *any* member matches — it is a union. Media Queries Level 4 added an explicit `or` keyword usable between parenthesised conditions: ```css @media ((width < 30rem) or (orientation: portrait)) { } ``` The catch is that you may not mix `and` and `or` at the same nesting level without parentheses — the grammar forbids the ambiguous `A and B or C` precisely so that nobody has to memorise a precedence table. Parenthesise, or fall back to the comma form, which every browser has understood since media queries shipped. ## NOT `not` at the front of a query negates *that whole query*: ```css @media not screen and (width >= 40rem) { } ``` This is read as `not (screen and (width >= 40rem))` — it applies to everything except wide screens, including print at any width. It does **not** mean "non-screen media that are wide". Because negation binds to the entire query, `not` in one member of a comma list affects only that member: ```css @media not print, (width >= 60rem) { } ``` Level 4 also permits negating an individual condition, which is often what you actually want: ```css @media (not (hover: hover)) { .tooltip { display: none; } } ``` ## `only` `only` is the fossil in the syntax. In the era of browsers that understood media *types* but not media *features* — notably Internet Explorer 8 and earlier — a rule like `@media screen and (min-width: 40em)` would be parsed as plain `@media screen` and applied unconditionally, breaking layouts. Prefixing `only` produced a token those browsers did not recognise, so they skipped the rule entirely. In every current browser `only` has no effect whatsoever; it is legal, it must be followed by a media type, and its presence in a modern stylesheet is copy-paste inheritance, not technique. ## Media types worth knowing Only three matter in practice: `all` (the default), `screen`, and `print`. `speech` exists for speech synthesisers. The long tail from the CSS 2.1 era — `tty`, `tv`, `projection`, `handheld`, `braille`, `aural` — was deprecated in Level 4; browsers keep them parseable so old stylesheets don't break, but they never match. In particular `handheld` never meant "phone" in any browser you will meet, and a query aimed at it is dead code. A related instinct worth resisting: media *types* are not device categories. There is no `@media mobile`. Everything a phone browser does is `screen`, and the way you distinguish it is by querying dimensions or input capability, never by type. ## Invalid queries fail closed A malformed query — a stray unparenthesised condition, an unknown feature name, a comparison operator on a discrete feature — is invalid, and an invalid query simply never matches. Nothing is logged in the page, and the entire block silently does nothing. When a media block "isn't applying," checking the query's validity before debugging the declarations inside it saves a lot of time. In a comma list, one invalid member is dropped while the valid ones still work, which can make a partially-broken rule look intermittently correct.
- What does @media not screen and (width >= 40rem) actually match?Everything except a wide screen. The `not` negates the whole query, so it reads as `not (screen and width >= 40rem)` — it matches print at any width, and it matches screens narrower than 40rem. It does *not* mean "non-screen media that happen to be wide." If you want to negate only the feature, use the Level 4 form `@media screen and (not (width >= 40rem))`.
- Is there a media type that targets phones?No. Every graphical browser, on a phone or a desktop, reports `screen`; the CSS 2.1 types like `handheld` and `tv` were deprecated in Level 4 and never match. You distinguish contexts by querying what actually differs — viewport dimensions, `orientation`, `pointer` and `hover` — because a phone is not a device class in CSS, it is a small viewport with a coarse pointer.
- Does the orientation media feature describe the device or the viewport?The viewport. `(orientation: landscape)` matches whenever the viewport is wider than it is tall, so a desktop window dragged wide matches landscape and a tall narrow browser window on the same monitor matches portrait. It says nothing about how the physical device is being held, which is why width-based queries usually express layout intent more directly.
saying these in an interview costs you the question
- Reads the comma as AND rather than OR
- Thinks not negates only the condition after it
- Believes only screen is needed for modern browsers
- Looks for a mobile or handheld media type
- Assumes a broken query throws a visible error