Разбираем спорную новинку 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() позволяет писать такой же отвратительный код, как в препроцессорах, но делать это нативно.
Всё же хочется верить, что эту функцию будут развивать. А текущий релиз — это и не провал, и не прорыв. Это «препатч накануне большого контентного аддона».