Похоже, @custom-media всё-таки живо

22.11.2025 • css

Проблема

Обычно константы выносят в определённое место, будь то CSS или JS:

const ANIMATION_LENGTH = 100;
:root{
    --column-width: 100px;
}

В CSS, конечно, CSS-переменные не являются константами, но это частый случай использования. Мы выносим цвета, размеры, параметры теней и многое другое. В общем, делаем всё возможное, чтобы интерфейс был единообразным, а для конструирования нового уже был понятный набор переменных. Всё это называют “дизайн-токенами” и “дизайн-системами”. Но в реальности эта конструкция разбивается об одну старую, но очень полезную возможность CSS: Media Query. В месте, в котором мы хотим прописать условие на размер экрана, обычно пишется следующее:

@media (max-width: 1024px) {
    ...
}

С помощью разных ширин часто делают дизайн сайта под телефоны, планшеты, большие мониторы. И такие @media могут встречаться в количестве десятков штук в разных местах проекта. Конечно же, их хочется вынести в константы, чтобы весь сайт работал единообразно. Но как это сделать? CSS-переменные работают только на DOM-элементах, их нельзя использовать в @media. Конечно, есть всевозможные пре- и пост-процессоры, которые решат эту проблему, но решение всё же хотелось видеть именно в CSS.

Появление @custom-media

@custom-media успешно решает проблему выноса констант из @media:

@custom-media --desktop-window (min-width: 1024px);
 
@media (--desktop-window) {
    ...
}

Мне удалось найти упоминания @custom-media в спеке аж 2014го года. Это за 2 года до релиза CSS-переменных!. Я не уверен, что происходило следующие 7 лет, но потом следы находятся в 2021м году, тогда фича попала в спеку Media Queries Level 5. В 2023м году появилась заявка на добавление @custom-media в Interop 2024. Она была отклонена (возможно, из-за отсутствия тестов).

Через год дела обстояли уже куда лучше. Тогда добавили фичу в Browser Compat Data, написали тесты в Web Platform Tests и даже сделали документацию в MDN.

@custom-media были поданы в виде заявки на Interop 2025.

Конец?

Тот пул-реквест с тестами так и не был смёржен, как и документацию в MDN. Заявку в Interop снова не приняли. По итогу фичу из Browser Compat Data удалили в том же 24м году. Мотивация была в том, ни в одном браузере фича не реализована, несмотря на нахождение в спеке много лет.

Некоторые разработчики посмотрели на всё это и решили, что фича умерла, не родившись.

Воскрешение

В июле 25го года появился новый минимальный набор тестов, который был вмёржен, в отличии от предыдущего. Тогда же появилась и страница фичи на chromestatus. А в октябре 25го года появилась первая браузерная реализация! В 146й версии Файерфокса, за флагом layout.css.custom-media.enabled, таки должна выехать эта возможность. В хромиуме, судя по ишью, работа ведётся прямо в данный момент.

Как использовать уже сейчас?

Прямо сейчас есть несколько возможностей по использованию.

postcss-custom-media

Плагин появился очень давно, и подойдёт при использовании PostCSS. В этом блоге он как раз используется для нового синтаксиса.

LightningCSS

LightningCSS тоже поддерживает @custom-media. И очень похоже, что поддержка есть буквально с первых версий проекта.

Альтернативы

Пара альтернативных подходов найдётся, и достаточно интересных.

Style Queries

Можно описать Media Query один раз, и применить в нём кастомное свойство:

:root {
    --is-mobile: false;
 
    @media (max-width: 1024px) {
        --is-mobile: true;
    }
}

Дальше можно запросить значение через Style Query:

@container style(--is-mobile: true) {
    ...
}

Кастомные env()

Существует ещё одна задумка: возможность объявлять свои собственные env() значения. Это позволит использовать их в @media:

@media (max-width: env(--phone-width)) {
    ...
}

Есть плагин к PostCSS с реализацией.

Фича не содержится ни в одной из спек на данный момент, но, возможно, это изменится в будущем?

Итог

Похоже, долгострой, который длится уже 11 лет, близится к счастливому завершению и мы таки получим @custom-media в скором будущем. В текущей сборке Firefox Nightly фича у меня, к сожалению, не заработала, но я не могу не нарадоваться подобной активности со стороны браузеров и веб-платформы.