Какая специфичность у тегов, классов и inline-стилей в CSS
Что проверяют
Знаете ли вы разряды специфичности и понимаете ли, что она сравнивается поразрядно, а не суммой.
Как отвечать
Специфичность это тройка чисел, которая считается так:
- первый разряд: количество идентификаторов;
- второй разряд: количество классов, псевдоклассов и селекторов по атрибуту;
- третий разряд: количество тегов и псевдоэлементов.
Примеры: p даёт 0,0,1; .card даёт 0,1,0; #header даёт 1,0,0; .card p.title даёт 0,2,1.
Сравнение идёт поразрядно слева направо, а не сложением. Поэтому один идентификатор сильнее любого числа классов: 1,0,0 больше, чем 0,20,0. Это ровно та причина, по которой идентификаторы не используют для стилей.
Отдельно стоят два случая:
- инлайн-стиль в атрибуте сильнее любого селектора;
!importantперебивает всё, включая инлайн, и уступает только другому!importantс более высоким приоритетом источника.
Что не влияет на специфичность: универсальный селектор и комбинаторы (потомок, дочерний, соседний).
Современные тонкости, которые стоит назвать:
:not(),:is()и:has()сами по себе ничего не добавляют, но берут специфичность самого специфичного аргумента внутри;:where()всегда даёт ноль. Это специально сделано для библиотек и сбросов: правило применяется, но не мешает переопределению;- слои каскада сравниваются до специфичности. Правило из более позднего слоя выигрывает у более специфичного правила из раннего.
При равной специфичности побеждает то правило, которое идёт позже в порядке подключения.
Практический вывод: держать специфичность низкой и плоской. Соглашения об именовании и модули стилей нужны именно для этого, а не только для читаемости.
Где спотыкаются
Складывают разряды и считают десять классов сильнее идентификатора.
Лечат каскад расстановкой !important.
Не знают про :where() и его нулевую специфичность.
Пишут длинные цепочки селекторов, после чего переопределить их можно только ещё более длинной.