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

Если у вас есть два (или более) конфликтующих правила CSS, относящихся к одному и тому же элементу, то для определения более приоритетного, браузеры используют определенные критерии отбора.

Вникание в эти критерии отбора может показаться не таким уж и важным делом. Да и в большинстве случаев никакие конфликты вам не грозят. Однако, чем объемнее и сложнее файлы стилей, или чем их больше, тем более велика вероятность возникновения подобных конфликтов.

Что такое специфичность?

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

Думайте о специфичности, как о некоем рейтинге, который определяет, какая декларация стиля в конечном итоге будет применена к элементу.

Посмотрите на следующие примеры:

Пример 1

В этом примере мы используем селектор элемента "p" и определяем для него красный цвет. Текст будет красным:


<html>
<head>
  <style>
    p { color: red; }
  </style>
</head>
<body>

<p>Привет всем!</p>

</body>
</html>

Теперь посмотрим на следующий пример.

Пример 2

В этом примере мы добавили селектор класса (с именем "test") и определили для него зеленый цвет. Теперь текст будет зеленым (даже несмотря на то, что для селектора элемента "p" у нас определен красный цвет). Это из-за того, что у селектора класса более высокий приоритет:


<html>
<head>
  <style>
    .test { color: green; }
    p { color: red; }
  </style>
</head>
<body>

<p class="test">Привет всем!</p>

</body>
</html>

Следующий пример.

Пример 3

В этом примере мы добавили селектор идентификатора (с именем "demo"). Теперь текст будет синим, потому что у селектора идентификатора еще более высокий приоритет:


<html>
<head>
  <style>
    #demo { color: blue; }
    .test { color: green; }
    p { color: red; }
  </style>
</head>
<body>

<p id="demo" class="test">Привет всем!</p>

</body>
</html>

Следующий пример.

Пример 4

В этом примере для элемента <p> мы добавили внутриэлементный стиль. Теперь текст будет розовым, потому что у внутриэлементных стилей самый высокий приоритет:


<html>
<head>
  <style>
    #demo { color: blue; }
    .test { color: green; }
    p { color: red; }
  </style>
</head>
<body>

<p id="demo" class="test" style="color: pink;">Привет всем!</p>

</body>
</html>

Иерархия специфичности

У каждого CSS селектора есть свое место в иерархии специфичности.

Существует четыре категории, которые определяют уровень специфичности селектора. Чем выше категория, тем выше приоритет:

  1. Внутриэлементные стили - Пример: <h1 style="color: pink;">
  2. Селекторы идентификаторов - Пример: #navbar
  3. Селекторы классов, псевдоклассов, атрибутов - Пример: .test, :hover, [href]
  4. Селекторы элементов и псевдоэлементов - Пример: h1, ::before

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

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

Вот как рассчитывается специфичность.

Каждому селектору в зависимости от его категории присваивается определенный коэффициент. Начинается все с 0. Затем каждому селектору идентификатора прибавляется значение 100, каждому селектору класса (или псевдокласса, или атрибута) - значение 10 и каждому HTML селектору или псевдоэлемента - значение 1.

Внутриэлементные стили имеют коэффициент специфичности 1000, что всегда дает им самый высокий приоритет!

Примечание: Из этого правила есть одно исключение - если используется модификатор !important, то этот стиль будет переопределять даже внутриэлементные стили!

У комбинированных селекторов специфичность вычисляется путем сложения коэффициентов всех входящих в него селекторов.

В следующей таблице показаны примеры того, как вычисляется значение специфичности:

СелекторЗначение специфичностиВычисление
p11
p.test111 + 10
p#demo1011 + 100
<p style="color: pink;">10001000
#demo100100
.test1010
p.test1.test2211 + 10 + 10
#navbar p#demo201100 + 1 + 100
*00 (универсальный селектор игнорируется)

Селектор с самым большим значением специфичности побеждает, и его стиль применяется к элементу!

Рассмотрим три фрагмента кода:


A: h1
B: h1#content
C: <h1 id="content" style="color: pink;">Заголовок</h1>

Специфичность A = 1 (один селектор элемента)
Специфичность B = 101 (один селектор элемента + один селектор идентификатора)
Специфичность C = 1000 (внутриэлементный стиль)

Поскольку у третьей декларации (C) самое большое значение специфичности (1000), то эта декларация и будет использоваться.

Еще примеры правил специфичности

При равной специфичности применяется последняя по месторасположению в таблице стилей декларация:


h1 {background-color: yellow;}
h1 {background-color: red;}

Заголовки будут красными, а не желтыми.

У селекторов идентификаторов более высокая специфичность, чем у селекторов атрибутов. Посмотрите на следующие три строки кода:


div#a {background-color: green;}
#a {background-color: yellow;}
div[id=a] {background-color: blue;}

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

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


Из внешнего CSS файла:
#content h1 {background-color: red;}

В HTML файле:
<style>
#content h1 {background-color: yellow;}
</style>

применяться будет последняя декларация.

Селектор класса побеждает любое количество селекторов элементов. Селектор класса вроде .intro перекроет селекторы элементов h1, p, div и т. д.:


.intro {background-color: yellow;}
h1 {background-color: red;}

Универсальный селектор (*) имеет нулевую специфичность. Универсальный селектор (*) и наследуемые значения игнорируются!