Специфичность селекторов в CSS

Владислав Белецкий
Владислав Белецкий .
Категория:
Комментариев: 0

Вы сверстали страницу, пишете стили и вдруг понимаете — что-то не так. Текст, который должен быть зелёным, почему-то остался красным:

<p class="text">Это просто текст</p>

.text {
    color: red;
}

p {
    color: green;
}

Вы столкнулись со специфичностью селекторов: свойства не переопределились, потому что у .text больший вес. Давайте разбираться, что здесь происходит.

Что такое специфичность селекторов

Разработчики часто применяют к одному элементу сразу несколько CSS-правил. Если два свойства из разных правил конфликтуют, браузер смотрит на селекторы. Свойство из CSS-правила с более «сильным» селектором побеждает в конфликте.

💡 Специфичность определяет приоритет CSS-правил у разных селекторов.

Как распределяется специфичность:

  • Наибольшая специфичность у встроенных стилей.
  • Меньше — у селекторов идентификаторов.
  • Ещё меньше — у классов, псевдоклассов и селекторов атрибутов.
  • Самый низкий приоритет у селекторов типов элемента и псевдоэлементов.

«Перебить» специфичность встроенных стилей можно только одним способом — использовать модификатор !important. Но это плохая практика: такие стили почти невозможно переопределить. Разве что использовать более специфичный селектор и указать CSS-правило с ещё одним !important.

Как посчитать специфичность селекторов

Порой в коде встречаются сложные конструкции. Например, стили для элемента <li> в меню:

ul .list-item.list-active {
    color: blue;
}

ul #catalog.list-item {
    color: yellow;
}

Чтобы определить, какое из правил применится, надо посчитать вес селекторов. Чем больше вес, тем выше специфичность.

Вес записывается в виде a, b, c, d, где:

  • a — встроенные стили,
  • b — селектор по идентификатору,
  • c — селектор классов псевдоклассов и атрибутов,
  • d — селектор по тегу и псевдоэлементу.

Если в цепочке есть один из этих селекторов, то на его место в строке a, b, c, d ставится единица. Если нет — нуль.

Посчитаем на примере ul .list-item.list-active:

  • Встроенных стилей нет. Ставим нуль — 0, b, c, d.
  • Идентификатора тоже нет, добавляем на его место нуль — 0, 0, c, d.
  • Есть два класса, каждый весит единицу. Складываем их и подставляем в формулу: 0, 0, 2, d.
  • Тег один, ставим 1.

Получается, вес ul .list-item.list-active — 0, 0, 2, 1.

Теперь можно рассчитать вес ul #catalog.list-item. Здесь тоже нет встроенных стилей, но есть один идентификатор, класс и тег. Получаем 0, 1, 1, 1.

Сравниваем вес селекторов — у второго он больше, поэтому пункт меню станет жёлтым.

💡 Сложно запомнить? Считайте специфичность в онлайн-калькуляторе.

Специфичностью можно управлять. Например, если вы хотите придать веса селектору, навесьте на него дополнительный тег или класс: .news.news.main-news. Только не используйте длинные цепочки. Идеально, когда вложенность селекторов не больше трёх — такой код проще читать и поддерживать. Если же селекторов больше — возможно, стили стоит переписать.

Нюансы

Селекторы с использованием + и ~ , а также псевдокласс :where() не увеличивают уровень вложенности.

Специфичность не зависит от последовательности селекторов. У .list-item#catalog и #catalog.list-item одинаковый вес.

Псевдокласс :not не учитывают при подсчёте специфичности — считают только расположенные в нём селекторы.

Немного практики

Вес селектора — 0, 1, 2, 0.

Вес #popup-button — 0, 1, 0, 0

Вес .popup-button.popup.link.button.green-button.big-button.decorate-button.shadow-button.square-button.border-button:hover — 0, 0, 11, 0.

Первый селектор специфичнее. Хотя у второго селектора 10 классов (никогда не делайте так) и псевдоэлемент, его вес ниже.

<button style="background-color: blue" type="button">Это кнопка</button>

button {
    background-color: black !important;
}

Кнопка будет чёрной. Модификатор !important даёт наивысший приоритет.

Материалы по теме

  • Как работает каскад в CSS
  • Что такое выражения от стилей
  • Свойство display в CSS
  • Простая анимация на чистом CSS
Подписаться
Уведомить о
guest
0 комментариев
Межтекстовые Отзывы
Посмотреть все комментарии