CSS has if() now: conditional styles without stacking media queries

Chrome 137 shipped the CSS if() function, which lets any property value branch on a custom property, a media query or feature support. It does not replace media queries, but it collapses a lot of duplicated blocks.

Expressing “use A if the condition holds, otherwise B” in CSS used to mean repeating whole declarations:

.card { padding: 16px; }
@media (min-width: 60rem) { .card { padding: 24px; } }

Since Chrome 137 the same thing fits on one line:

.card {
  padding: if(media(min-width: 60rem): 24px; else: 16px);
}

What it can test

if() accepts three kinds of conditions:

  • style(--theme: dark) — the value of a custom property;
  • media(...) — a media query;
  • supports(...) — whether the browser supports a feature.

Branches are evaluated in order; the first true one wins, and else is the fallback. Because it sits in the value position, it works for any property: color, padding, grid-template-columns.

The real problem it solves

Theme switching usually means writing the same selector once per skin:

[data-skin='riso'] .card { border-width: 3px; }
[data-skin='ink'] .card { border-width: 1px; }

With if() you can push “the skin decides the border width” into a token:

:root {
  --card-border: if(
    style(--skin: riso): 3px;
    style(--skin: blueprint): 2px;
    else: 1px
  );
}

The win is not fewer keystrokes, it is centralising the difference: a new skin changes a token, not a selector list.

Division of labour with media and container queries

  • When the whole layout changes shape (a sidebar going from horizontal to vertical), keep using @media or @container — it reads better;
  • When one value changes with a condition, if() is more direct;
  • When the entire site changes theme, custom properties plus if() is the least painful combination.

Handling support

Until every engine ships it, treat it as progressive enhancement: write a plain fallback declaration first, then override with if(). Browsers that do not understand if() drop the whole declaration and keep the fallback — the usual CSS failure mode, which is exactly what you want.

.card { padding: 16px; padding: if(media(min-width: 60rem): 24px; else: 16px); }

The judgement

if() is not “JavaScript in CSS”. It does one thing: choose a value conditionally. But values are the most volatile part of a stylesheet, so that one ability removes a lot of duplicated blocks. The real payoff shows up in design systems, where differences live in tokens instead of scattered selectors.

Cover image: CSS3 logo (Wikimedia Commons).

← Back to all posts

Comments

…