Каскад и наследование
Правила приоритета CSS, наследование свойств, inherit/initial/unset/revert, важность и как не тонуть в конфликтах стилей.
1. Что такое каскад
Каскад — это система правил, по которой браузер выбирает «какое стилевое правило победит», когда их несколько. Порядок игры: важность → специфичность → порядок в файле. Понимание каскада — половина мастерства CSS.
- важность: !important и author > user > browser;
- специфичность: id > класс > тег;
- порядок: одинаковые по силе — последний в файле побеждает;
- каскадные слои (@layer) меняют правила по слоям.
2. Наследование
Часть свойств наследуется от предка к потомку: color, font-*, line-height, text-align, visibility, list-style. Другие (width, height, margin, border, background) — не наследуются: их значения берутся только с самого элемента.
.group { color: #0f172a; font-size: 1rem; }
/* потомки .group получают color и font-size автоматически —
но background у них прозрачный: он не наследуется */- наследующие — «текстовые» свойства;
- ненаследуемые — «коробочные»: размеры и отступы;
- список наследующих свойств не нужно помнить — он логичен.
3. inherit, initial, unset, revert
Четыре ключевых значения «вернуть по умолчанию» решают прилипшие каскады: inherit — взять от родителя, initial — стандартное значение свойства, unset — сбросить (inherit для наследующих, initial для остальных), revert — вернуть стили браузера/пользователя.
.inherited { color: inherit; } /* всегда как у родителя */
.reset-btn { font: inherit; } /* кнопки не наследуют шрифт — включаем */
.break-all { all: unset; } /* сбросить всё */
.form p { margin: revert; } /* вернуть браузерный марджин */4. Специфичность коротко
/* вес: id(1,0,0) > класс/атрибут(0,1,0) > тег(0,0,1) */
#app .title { color: red; } /* (1,1,0) */
.page .title { color: blue; } /* (0,2,0) */
h1.title { color: green; } /* (0,1,1) */
/* побеждает #app .title — ноль разрядом id */- специфичность решают от левой колонки к правой;
- равный вес решает порядок в файле;
- специфичность псевдоклассов — как класс, псевдоэлементов — как тег.
5. !important
!important поднимает правило над всеми того же элемента. Им лечат чужие стили (библиотеки, старые баги), но в своём коде оно — красный флаг: показывает, что каскад борется.
.el { color: red !important; } /* побеждает всё */
/* лучше: более сильный селектор или @layer */
.page .el { color: red; }6. Каскадные слои @layer
@layer задаёт явный порядок: стили из поздних слоёв перекрывают ранние, независимо от специфичности. Это снимает «войну» селекторов и упрощает переопределение.
@layer reset, base, components, utilities;
@layer base {
a { color: #2563eb; }
}
@layer components {
/* даже сильные по специфичности правила из components
уступают utilities и могут быть перекрыты там */ }
@layer utilities {
.u-link { color: inherit; }
}- порядок слоёв задаётся объявлением @layer один раз;
- слой без объявления в перечне — идёт первым по умолчанию;
- @import ы подключаются как parts слоёв.
7. Каскадные функции слоёв и specificity
Слои не отменяют специфичность внутри слоя: два правила одного слоя всё ещё борются по весу и порядку. Слой лишь определяет борьбу между слоями.
- управлять «весом» можно и самим @layer, и простой специфичностью;
- поздний слой важнее раннего, !important внутри слоя — наоборот;
- @layer решает проблемы, которые нельзя точечно обойти.
8. Каскад и важность
Итоговая шкала:important авторских, затем важные слои, потом обычные правила слоёв в порядке слоёв, потом неигровые (неважные) в порядке файла. Шкалу помнить не нужно — достаточно порядка: важность > спецификация > источник > порядок.
/* «перекрыть стиль компонента» — лучше слой, чем !important:
@layer components; /* объявили позже остальных */
/* если идёте против библиотеки — никто не запрещает layer и чужих */9. Практика: диагностика каскада
Когда стиль «не применяется»: DevTools покажет вычеркнутые правила и их вес. В панели Styles напротив каждого правила указана специфичность и источник.
- правило зачёркнуто, вес выше — побеждает другое, ищи причину;
- импорт исходного файла даёт стили-недостижимость (уберите);
- тёмная тема переопределяет через класс или переменные.
10. Наследующие свойства на практике
.app { color: #111827; font-family: system-ui, sans-serif; }
/* обычный текст по всему сайту унаследован — чётких font-face в блоках нет */
.btn { font: inherit; } /* по умолчанию кнопки НЕ наследуют шрифт —
приводим в систему */- устанавливайте базовые шрифты на body — потомки наследуют;
- кнопки, select и textarea не наследуют font и color — поставьте font: inherit;
- наследуйте, где логично, сбрасывайте, где инородно.
11. Чек-лист каскада
- приоритет правил проясняется по шкале: важность → спецификация → порядок;
- наследуемые свойства хранят «базовые» шрифты и цвета;
- inherit/initial/unset/revert — инструменты «вернуть»;
- !important — только для внешних библиотек, не для своего кода;
- @layer задаёт явный порядок и решает войны правил;
- специфичность плоская: классы, порядок файла вместо бремени id.
Что дальше
Курс завершён.