Наводим порядок в каскаде с использованием CSS @layer
- 30 апреля 2026
Если вы когда-нибудь подключали стороннюю библиотеку стилей и потом пытались её переопределить — вы знаете эту боль. Пишете правило, оно не работает. Добавляете класс поконкретнее — всё равно не работает. В итоге пишете !important и расстраиваетесь, потому что теперь нужно всё время учитывать это в дальнейшей работе.
Это называют войной специфичности. При равных прочих условиях браузер сравнивает специфичность селекторов раньше, чем порядок правил в коде. Поэтому более позднее правило с менее специфичным селектором может не сработать.
В 2022 году в браузерах появился @layer — способ самим расставить приоритеты между группами стилей.
Попробуйте сами
Нажмите на кнопки, чтобы включать и выключать слои и посмотреть, как меняется результат:
Для обычных деклараций авторских стилей последующий слой имеет приоритет над предыдущим, даже если селектор предыдущего слоя специфичнее.
Как это работает
Сначала объявляем порядок слоёв одной строкой:
@layer reset, base, components, utilities;
Для обычных деклараций это как оглавление: utilities имеет приоритет над components, а тот — над base. Потом наполняем каждый слой стилями:
@layer reset {
* { margin: 0; padding: 0; box-sizing: border-box; }
}
@layer base {
body { font-family: sans-serif; color: #333; }
}
@layer components {
.button { padding: 8px 16px; background: blue; color: white; }
}
@layer utilities {
.hidden { display: none; }
}
Для обычных деклараций авторских стилей слой utilities имеет приоритет над components, даже если у components более специфичный селектор.
Главный сценарий — укрощение библиотек
Импортируем библиотеку в слой bootstrap, а собственные стили помещаем в следующий слой. @import находится на верхнем уровне, до блоков со стилями; объявление порядка слоёв можно поставить перед ним:
@layer reset, bootstrap, my-styles;
@import url("bootstrap.min.css") layer(bootstrap);
@layer my-styles {
/* Обычные декларации этого слоя имеют приоритет над bootstrap. */
.btn { background: green; }
}
Обычные декларации в слое my-styles имеют приоритет над обычными декларациями в bootstrap, независимо от специфичности селекторов.
Стили вне слоёв
Обычные декларации вне слоёв имеют приоритет над обычными декларациями внутри слоёв. Это удобно для срочных переопределений, но легко запутывает:
@layer base {
.title { color: blue; } /* проиграет */
}
/* Для обычных деклараций стиль вне слоя имеет приоритет. */
.title { color: red; }
Для деклараций с !important порядок слоёв обратный: первый слой важнее последующих, а важные декларации внутри слоёв имеют приоритет над важными декларациями вне слоёв. Обычная декларация в позднем слое не переопределит декларацию с !important в раннем.
Поддержка в браузерах
@layer работает в Chrome 99+, Firefox 97+, Safari 15.4+. Полная поддержка во всех современных браузерах. Актуально на caniuse.com.
Что запомнить
@layer — это способ навести порядок в каскаде без борьбы со специфичностью. Вы сами решаете, какая группа стилей важнее, — и браузер следует этому порядку.
Чтобы лучше понять, как браузер вообще решает конфликты стилей, почитайте про специфичность селекторов и как работает каскад в CSS.
«Доктайп» — журнал о фронтенде. Читайте, слушайте и учитесь с нами.