May 22, 2020

[7 урок] Спецификация CSS

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

Исключение из правил - !important

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

Несколько практических советов:

  • Всегда пытайтесь использовать специфичность, а !important используйте только в крайних случаях
  • Используйте !important только в страничных стилях, которые переопределяют стили сайта или внешние стили (стили библиотек, таких как Bootstrap или normalize.css)
  • Никогда не используйте !important, если вы пишете плагин или мэшап.
  • Никогда не используйте !important в общем CSS сайта.

Вместо !important можно:

  1. Лучше использовать каскадные свойства CSS
  2. Использовать более специфичные правила. Чтобы сделать правило более специфичным и повысить его приоритет, укажите один элемент или несколько перед нужным вам элементом:

Вне зависимости от порядка следования правил, текст всегда будет зелёным, поскольку у этого правила наибольшая специфичность (при этом, правило для голубого цвета имеет преимущество перед правилом для красного, несмотря на порядок следования).

Вам придется использовать !important если:

А) Первый сценарий:

  1. У вас есть общий файл стилей, устанавливающий правила для внешнего вида сайта.
  2. Вы пользуетесь (или кто-то другой пользуется) весьма сомнительным средством - объявлением стилей непосредственно в элементах

В таком случае вам придется объявить некоторые стили в вашем общем файле CSS как !important, переопределяя, таким образом, стили, установленные в самих элементах.

Пример из практики: Некоторые плохо написанные плагины jQuery, использующие присваивание стилей самим элементам.

Б) Еще сценарий:

Как сделать цвет текста в абзацах awesome красным всегда, даже если они расположены внутри #someElement? Без !important у первого правила специфичность больше и оно имеет преимущество перед вторым.

Как преодолеть !important

A) Просто добавьте еще одно правило с модификатором !important, у которого селектор имеет большую специфичность (благодаря добавлению типа элемента (тэга), идентификатора (атрибута id) или класса к селектору).

Пример большей специфичности:

Б) Или добавьте правило с модификатором !important и таким же селектором, но расположенное в файле после существующего (при прочих равных выигрывает последнее объявленное правило):

Не исключение - :not()

Отрицающий псевдокласс :not не учитывается как псевдокласс при расчете специфичности. Однако селекторы, расположенные внутри :not, при подсчете количества по типам селекторов рассматриваются как обычные селекторы и учитываются.

Следующий фрагмент CSS ...

... примененный к такому HTML ...

... отобразится на экране так:

Специфичность основана на форме

Специфичность опирается на форму селектора. В следующем примере, при определении специфичности селектора, селектор *[id="foo"] считается селектором атрибута, даже при том, что ищет идентификатор.

Эти объявления стилей ...

... примененные к нижеследующей разметке ...

... в результате выглядят так:

Потому что оба правила соответствуют одному и тому же элементу, но селектор идентификатора имеет большую специфичность.

Независимость от расположения

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

... в сочетании со следующим HTML ...

... отобразится как:

Потому что, хотя оба объявления имеют одинаковое количество типов селекторов, но селектор html h1 объявлен последним.

Непосредственно соответствующие элементы и унаследованные стили

Стили непосредственно соответствующих элементов всегда предпочитаются унаследованным стилям, независимо от специфичности унаследованного правила. Этот CSS ...

... с таким HTML ...

... тоже отобразится как:

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