Каскад и специфичность
Вопрос
Какое правило победит, если селекторы указывают на один элемент?
Короткий ответ
Каскад смотрит по порядку:
- Важность и происхождение:
!importantв авторских стилях бьёт обычное авторское правило. Стили пользователя и браузера участвуют по своим правилам, на практике чаще спорят ваши файлы. - Специфичность: inline-стиль, затем id, затем класс / атрибут / псевдокласс, затем элемент / псевдоэлемент. Считают кортежем, а не «суммой очков»: один id сильнее любого числа классов.
- Порядок в коде: при равной специфичности побеждает правило, которое идёт позже.
:where() обнуляет специфичность своего аргумента. :is() берёт специфичность самого сильного аргумента. @layer задаёт приоритет слоёв: неслоистые стили побеждают слоистые, внутри слоёв побеждает слой, объявленный позже.
Разбор
0,1,0,0 (один id) сильнее 0,0,10,0 (десять классов). Поэтому «добавлю ещё класс» не перебивает id.
BEM и utility-классы держат специфичность плоской, чтобы порядок и состав классов оставались предсказуемыми. Вложенный селектор из пяти уровней чинится только ещё более длинным селектором.
!important ломает эту лестницу. Его оставляют для редкого перебивания чужого виджета, а не для своих компонентов.
Наследование отдельно от каскада: color и font текут к потомкам, margin и display нет. inherit, initial, unset и revert явно выбирают источник.
На что смотрят на senior
@layer reset, components, utilities позволяет утилите перебить компонент без роста специфичности. Container queries (@container) меняют раскладку от размера родителя, а не вьюпорта: карточка в узкой колонке и в широкой ленте ведёт себя по-разному при одной ширине окна.
:has() стилизует родителя по наличию потомка, например форму, внутри которой есть :invalid. Это убирает часть классов, которые раньше вешали из JS.
Типичные ошибки
- Складывать специфичность в одно число и удивляться, что id победил.
- Чинить конфликт новым
!important. - Путать наследование с применением селектора к потомку.
Задача
Какой цвет будет у текста и почему?
<p class="text" id="lead">Текст</p>p { color: black; }
.text { color: green; }
#lead { color: navy; }Показать ответ
Победит #lead: у селектора с id специфичность выше, чем у класса и у тега. Порядок в файле тут ни при чём, если специфичность разная.
Цвет текста — navy.