Освой два новых критерия каскада - слои и близость области - чтобы выстраивать архитектуру стилей без войн специфичности.
Открыть этот урок в KodokonКаскад разрешает конфликтующие объявления по упорядоченным критериям: источник и важность, затем контекст, затем стили из атрибута style, затем слои (@layer), затем специфичность и, наконец, порядок появления. Ключевой момент: слои оцениваются раньше специфичности. Правило .button в слое с более высоким приоритетом побеждает #nav div.menu a.button из слоя пониже - его специфичность (1,2,2) не значит ничего против порядка слоёв. Именно это делает @layer таким мощным для архитектуры дизайн-системы: приоритет объявляется один раз и структурно, вместо того чтобы отвоёвывать его селектор за селектором.
@layer reset, base, components, utilities;
@layer components {
.button { background: rebeccapurple; }
}
@layer base {
button { background: gray; }
}Две тонкости спецификации, которые обязательно нужно знать. Первая: стили вне любого слоя побеждают слоистые стили (для обычных объявлений) - они образуют неявный слой, поставленный последним. Твои локальные переопределения поэтому всегда бьют слоистую библиотеку. Вторая: с !important порядок полностью переворачивается. Побеждают слои, объявленные первыми, а !important внутри слоя бьёт !important вне любого слоя. Объявление с !important в твоём слое reset становится почти непобедимым.
@layer base, theme;
@layer base {
a { color: black !important; }
}
@layer theme {
a { color: purple !important; }
}@scope ограничивает набор правил между корнем области и необязательной нижней границей: @scope (.card) to (.card__content) берёт элементы, которые являются потомками .card, но находятся вне .card__content - знаменитый donut scope, идеальный, чтобы стилизовать оболочку компонента, не протекая в подставляемое в неё содержимое. Внутри :scope указывает на сам корень. И @scope вводит совершенно новый критерий каскада: близость. При равной специфичности побеждает правило, чей корень области ближе к элементу - то, чего никогда не могли выразить ни BEM, ни комбинаторы.
@scope (.card) to (.card__content) {
:scope {
padding: 1rem;
border: 1px solid oklch(0.85 0.02 260);
}
img { border-radius: 8px; }
}