Специфичность стилей.

Free Preview
Продолжительность: 13 мин

В прошлом уроке мы встретили понятие специфичность. Давайте разберем что это такое.

Представьте ситуацию, когда к одному и тому же HTML-элементу применяются два CSS-правила, которые задают одно и то же свойство, но описаны разными селекторами.

Рассмотрим пример:

<p id="text" class="paragraph">Пример текста</p>
<style>
  #text {
    color: red;
  }

  .paragraph {
    color: blue;
  }

  p {
    color: black;
  }
</style>
html

Как думаете какой цвет текста будет внутри абзаца?

Возможно, вы ответите что применится последний стиль или все одновременно, но в данном случае текст станет красным.

Браузер действует по чётким правилам и селектор #text имеет большую специфичность, чем .paragraph и p, поэтому и будет применен.

Определение специфичности

Когда к одному элементу применяются несколько CSS-правил, браузер должен решить, какое из них важнее. Для этого и существует понятие специфичности.

Специфичность — это механизм, с помощью которого браузер определяет, какое CSS-правило будет применено, если несколько правил конфликтуют между собой.

Когда несколько CSS-правил применяются к одному элементу и конфликтуют между собой, браузер действует по следующему алгоритму:

  1. Сравнивает специфичность селекторов;
  2. Если специфичность одинаковая — смотрит порядок следования в коде;
  3. Если и это не помогло — учитываются дополнительные правила (о них позже).

У каждого селектора есть свой "вес" - числовое значение обозначающее специфичность. При конфликте стилей сравнивает эти веса и применяет тот стиль, который имеет наибольшее значение специфичности.

Из чего складывается специфичность

Упрощённо специфичность можно представить в виде четырёх уровней:

  1. Inline-стили (style="")
  2. ID-селекторы (#id)
  3. Классы, атрибуты, псевдоклассы
  4. Теги и псевдоэлементы

Чем выше уровень — тем важнее селектор.

На самом деле, за каждым селектором реально существует числовое значение. Подробный разбор того как это работает можно найти в документации, но существуют упрощенные подходы, которые позволяют получить оценочное значение для понимания того какой стиль будет применен. Пример хорошего расчета можно найти например здесь.

Но в реальной разработке лучше вообще избегать необходимости расчета специфичности, и руководствоваться простым правилом - чем точнее селектор, тем выше его приоритет.

Супер оружие !important

Иногда бывает так, что какой-то элемент уже имеет очень специфичные стили, а нам нужно его переопределить. Например, такие случаи возникают при использовании сторонних библиотек компонентов. Представьте себе такую ситуацию - мы используем компонент кнопки и у нее уже есть инлайн стили задающии цвет. Нам нужно переопределить этот стиль, но мы не можем редактировать код самой кнопки.

<button id="success" style="background-color: green;">OK</button>
html

Инлайн стиль имеет наивысшую специфичность и даже если мы добавим стиль по селектору id это ничего не изменит. В таком случае нам поможет ключевое слово !important которое может придать стилю максимальную специфичность и "перебить" все другие объявления. Чтобы это заработало нужно добавить !important после соответсвующего значения CSS-свойства:

#success {
  background-color: lightgreen !important;
}
css

Ключевое слово !important принудительно повышает приоритет CSS-свойства, игнорируя обычные правила специфичности. После его применения браузер не сравнивает селекторы, а учитывает только его наличие. Если несколько правил содержат !important, тогда браузер снова сравнивает их специфичность.

Несмотря на свою силу, !important крайне не рекомендуется использовать в обычной верстке. Он усложняет поддержку кода, вынуждает использовать ещё больше !important и делает поведение стилей непредсказуемым. Очень часто !important — это признак того, что CSS-архитектура построена неправильно.

Перед тем как использовать его задайте себе вопрос: «Могу ли я решить эту задачу без !important?». В большинстве случаев ответ - да.