Если вы когда-нибудь подключали стороннюю библиотеку стилей и потом пытались её переопределить — вы знаете эту боль. Пишете правило, оно не работает. Добавляете класс поконкретнее — всё равно не работает. В итоге пишете !important и расстраиваетесь, потому что теперь нужно всё время учитывать это в дальнейшей работе.

Это называют войной специфичности. Возникает она потому, что CSS решает конфликты через длину и конкретность селекторов, а не через то, кто написал правило позже и кто важнее по смыслу.

В 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 или любую другую библиотеку и хотите, чтобы ваши стили всегда её перебивали? Заворачиваем библиотеку в слой:

@layer reset, bootstrap, my-styles;

@layer bootstrap {
  @import url("bootstrap.min.css");
}

@layer my-styles {
  /* всё что пишем сами — всегда победит */
  .btn { background: green; }
}

Теперь неважно, какие там селекторы внутри Bootstrap. Ваш слой объявлен последним — он главнее.

Стили вне слоёв

Важный момент: если написать стили вообще без @layer, они окажутся вне слоёв и будут иметь приоритет над всеми слоями. Это удобно для срочных переопределений, но легко запутывает:

@layer base {
  .title { color: blue; } /* проиграет */
}

/* вне слоя — всегда победит */
.title { color: red; }

Поддержка в браузерах

@layer работает в Chrome 99+, Firefox 97+, Safari 15.4+. Полная поддержка во всех современных браузерах. Актуально на caniuse.com.

Что запомнить

@layer — это способ навести порядок в каскаде без борьбы со специфичностью. Вы сами решаете, какая группа стилей важнее, — и браузер следует этому порядку.

Чтобы лучше понять, как браузер вообще решает конфликты стилей, почитайте про специфичность селекторов и как работает каскад в CSS.