Похоже, @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 фича у меня, к сожалению, не заработала, но я не могу не нарадоваться подобной активности со стороны браузеров и веб-платформы.