Разбираем спорную новинку 2025 года — CSS‑функцию if(), которая появилась в экспериментальном режиме в Chrome. Смотрим, как она работает, где помогает, где подводит и чего от неё ждать дальше.

Летом 2025 года в Chrome появилась экспериментальная функция if(). На первый взгляд это звучит как революция: наконец‑то условия в CSS! Но так ли всё радужно? Разберёмся спокойно и по шагам.

Что делает if()

CSS-функция if() позволяет задавать значение свойства в зависимости от условия. Она живёт прямо внутри значения — по духу это ближе к тернарному оператору, чем к полноформатному if в языках программирования.

Первый тип условий — style queries

Если переменная --scheme равна dark, фон станет серым.

body {
  --scheme: dark;

  background: if(
    style(--scheme: dark): gray;
  );
}

Если значение другое — функция вернёт Guaranteed-invalid value (по сути, эквивалент initial).

body {
  --scheme: color;

  background: if(
    style(--scheme: dark): gray;
  );
}

Обычный каскад игнорирует ошибочный код и не переопределяет значение свойства. А if, не нашедший подходящую ветку, жёстко сбросит значение свойства через initial.

Можно добавить ещё одно условие для обработки нового значения:

body {
  --scheme: color;

  background: if(
    style(--scheme: dark): gray;
    style(--scheme: color): lightblue;
  );
}

А чтобы обработать всё остальное — можно использовать ветку else прямо как во взрослых языках программирования:

body {
  --scheme: other;

  background: if(
    style(--scheme: dark): gray;
    style(--scheme: color): lightblue;
    else: tomato;
  );
}

Второй тип условий — медиавыражения

Функция умеет работать не только со стилевыми переменными, но и с медиазапросами:

h1 {
  font-size: if(
    media(width > 700px): 72px;
    else: 42px;
  );
}

Если ширина окна больше 700 px, шрифт увеличится до 72 px — иначе останется 42 px.

Третий тип условий — feature queries

if() также понимает проверки поддержки возможностей. Например, зададим цвет текста, если функция element() не поддерживается:

h1 {
  color: if(
    not supports(element("#myid")): red;
    else: white;
  );
}
Если нужно поменять один параметр — запись с if() выглядит аккуратно и экономит место.

Но давайте честно — всё это мы уже умеем делать другими способами.

Можно ли без if()? Можно.

Те же проверки реализуются стандартными директивами: @container, @media, @supports. Поведение будет тем же:

:root {
  --scheme: other;
}

body {
  background: tomato;
}

@container style(--scheme: dark) {
  body { background: gray; }
}

@container style(--scheme: color) {
  body { background: lightblue; }
}

@media (width > 700px) {
  h1 { font-size: 72px; }
}

@supports not (element("#myid")) {
  h1 { color: red; }
}

@supports (width: calc(1px * sibling-count())) {
  h1 { background-color: white; }
}

Промежуточный вывод. Функция if() не предоставляет новых возможностей. Это синтаксический сахар, который позволяет использовать существующие проверки на уровне значений свойств.

На первый взгляд, код с if() кажется более компактным, чем код с директивами. Однако это справедливо только в тех случаях, когда необходимо изменить значение только одного свойства. А это редкий случай.

Мы получили совсем не то, что ожидали?

Когда слышишь про «настоящий if в CSS», то представляешь сравнение переменных, которое активирует тот или иной набор свойств внутри CSS-правила:

.compare-numbers {
  --a: 5;
  --b: 10;

  if (var(--a) > var(--b)) {
    width: 100px;
    height: 200px;
  } else {
    width: 250px;
    height: 150px;
  }
}

Реальность оказалась куда скромнее: if() доступен только на уровне значения свойства. Без операторов < или >, без сложных сравнений, без нескольких переменных.

Всё, что мы можем проверить — равно ли значение переменной конкретному значению. Закачаешься:

.selector {
  --a: 5;
  width: if(style(--a: 5): 100px;);
}

И если перевести это на язык JS, получится примерно так:

let a = 5;
let width = (a === 5) ? "100px" : "";
«Насколько бы популярнее был JavaScript, если бы там были только такие мощные условия!»

Лучик надежды: самозапросы

Но не всё так плохо.

Важная деталь: if() умеет работать не только с переменными родителей (как в контейнерных стилевых запросах), но и с переменными самого элемента.

Посмотрим на пример:

h1 {
  font-size: if(
    style(--size: small): 32px;
    else: 72px;
  );
}

Пока --size не задан, срабатывает ветка else (72px). Если добавить переменную прямо в элемент — условие выполнится:

h1 {
  --size: small;

  font-size: if(
    style(--size: small): 32px;
    else: 72px;
  );
}

Это небольшое, но важное отличие: обычные директивы вроде @container проверяют родителей, а if() умеет проверять сам элемент.

Фантазии о будущем

Как можно прокачать if():

  • добавить операторы <, >, <=, >=;
  • добавить возможность сравнивать несколько переменных;
  • поднять if() на уровень CSS-правил.

Дополнительные операторы и сравнение нескольких переменных — самый вероятный вариант развития событий. Хотя, признаться честно, сравнивать CSS-переменные мы можем уже сейчас.

А вот поднять if() на уровень CSS-правил будет очень сложно.

Вердикт: провал или прорыв?

Если фича останется такой же как сейчас, то это полный провал. Добавьте её в чёрные списки своих линтеров и забудьте о ней навсегда. Потому что в текущем виде if() позволяет писать такой же отвратительный код, как в препроцессорах, но делать это нативно.

Всё же хочется верить, что эту функцию будут развивать. А текущий релиз — это и не провал, и не прорыв. Это «препатч накануне большого контентного аддона».