В дизайн-системах для SaaS, e-commerce и кабинетов reset, CSS из npm-пакетов, компоненты и utilities быстро начинают конкурировать. Частая ошибка - лечить это через
!important, .foo.foo и порядок импортов.Контракт слоев
Сначала зафиксируйте каскад явно:
@layer reset, vendors, tokens, base, components, utilities, overrides;
Чем слой правее - тем выше приоритет при одинаковом origin/importance. Специфичность работает внутри слоя, но между слоями сначала побеждает порядок
@layer.Production-пример
@import url("./reset.css") layer(reset);
@import url("./datepicker.css") layer(vendors);
@layer components {
.button { background: var(--accent); }
}
@layer utilities {
.bg-danger { background: var(--danger); }
}Теперь
.bg-danger предсказуемо переопределит фон компонента, даже если селектор компонента специфичнее. Не нужно делать .bg-danger.bg-danger или надеяться, что файл utilities подключится последним.Практичная схема
*
reset - нормализация браузерных стилей.*
vendors - datepicker, select, editor, carousel.*
tokens - CSS custom properties и темы.*
base - типографика и дефолты тегов.*
components - button, input, modal, tabs.*
utilities - атомарные override-классы.*
overrides - интеграционные фиксы, которые должны быть видимыми и редкими.Важные нюансы
Стили вне
@layer сильнее обычных layered-стилей. Поэтому договоритесь: весь CSS дизайн-системы живет в слоях, а приложение переопределяет ее через свой верхний слой.@layer app-overrides;
@layer app-overrides {
.checkout .button { min-width: 240px; }
}
Предупреждение: у
!important порядок слоев инвертируется. Не строите архитектуру вокруг него - layers нужны, чтобы снижать потребность в таких патчах.Вывод:
@layer превращает каскад из побочного эффекта сборки в явный API дизайн-системы, повышая предсказуемость layout и снижая визуальные регрессии.
