Приоритетность правил в css (Специфичность)

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

  • Применяет то правило , вес селекторов которого больше.
  • Если вес селекторов у всех правил одинаков, применяет правило, которое находится ниже всех в коде css.

Вес селекторов в css

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

0,0,0,0 или 0,1,0,2

Каждый селектор, например a или .header, прибавляет по единице в один из этих 4 рядов, в зависимости от своего типа.

Примеры рассчета приоритетности:
span {color: blue;}   /*Приоритетность равна 0,0,0,1*/

.parent1 span {color: red;}   /*Приоритетность равна 0,0,1,1*/

.big-parent .parent1 span {color: red;}   /*Приоритетность равна 0,0,2,1*/

#container div span {color: red;}   /*Приоритетность равна 0,1,0,2*/
				

В таком числовом ряду крайняя правая цифра имеет наименьший вес, а крайняя левая цифра - наибольший. Это означает что даже единица во 2-ом ряду справа больше, чем любая по величине цифра в первом. Тоесть:

0,0,1,0 больше чем 0,0,0,5 а 0,1,0,0 больше чем 0,0,2,5

В таблице ниже показано в какой ряд добавляет единицу каждый из существующих типов селекторов

Таблица распределения весов селекторов
Универсальный селектор * - Не имеет веса по отношению к другим селекторам, ничего не прибавляет - 0,0,0,0
Селекторы тэга (например div), а также псевдоэлементы (например :after) - 0,0,0,1
Селекторы классов (например .box), селекторы атрибутов (например a [ title="Главная страница" ]), а также псевдоклассы (например :hover) - 0,0,1,0
Идентификаторы (например #modal) — 0,1,0,0
Правила, написанные элементу непосредственно через атрибут style="" (инлайновые) - 1,0,0,0
Псевдокласс :not сам не имеет веса, а вот вес селекторов, которые являются его аргументами (например input:not( [ type="submit" ] )) считается как обычно.
Символы, обозначающие отношения селекторов + (соседние селекторы), > (непосредственный дочерний элемент) и ~ (родственные селекторы) не учитываются, их вес равен 0
Правила, написанные элементу в тегах <style></style> ничем не отличаются от обычных подключаемых стилей (style.css например), браузеры не делают различий между правилами из этих двух источников, не дают привилегий никому из них.
Примеры всех возможных сочетаний типов селекторов (с весом):
a {color: blue;}   /*Приоритетность равна 0,0,0,1*/

a.toplink {color: red;}   /*Приоритетность равна 0,0,1,1*/

#container .box a.toplink {color: red;}   /*Приоритетность равна 0,1,2,1*/

#container > .box + a.toplink {color: red;}   /*Приоритетность равна 0,1,2,1*/

a:after {color: red;}   /*Приоритетность равна 0,0,0,2*/

a:hover{color: red;}   /*Приоритетность равна 0,0,1,1*/

* a {color: red;}   /*Приоритетность равна 0,0,0,1*/

a:not([type="submit"]) {color: red;}   /*Приоритетность равна 0,0,1,1*/
				
<div style="color:red;"></div> <!--Приоритетность равна 1,0,0,0-->
				
Другие элементы, управляющие отображением
Стили браузеров по умолчанию (user agent styles, у каждого браузера свои, включаются только если элементам не задано никаких стилей) - имеют наименьший возможный приоритет среди всех стилей.
Атрибуты тегов, отвечающие за отображение элементов, такие как width="" или height="" - сильнее user agent стилей, но слабее любых селекторов. Их можно перебить даже с помощью универсального селектора *.

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

Пример 1
span {color: blue;}
.parent1 span {color: red;}
				
<div class="parent1">
	<span class="child"><span>
</div>
				

В данном случае специфичность первого правила равна 0,0,0,1, а специфичность второго — 0,0,1,1, так как во втором правиле тот же span определяется через родителя по классу .parent1.

Пример 2
span {color: blue;}
span {color: red;}
				

Вес селекторов обоих правил равен 0,0,0,1, поэтому применяется правило color: red, идущее в коде ниже.

Пример 3
.parent2 .parent1 span.child {color: blue;}
.parent1 span {color: red;}
				

Здесь применяется именно первое правило, несмотря на то, что второе идет в коде css, ниже, так, как вес первого правила (0,0,3,1) больше веса второго (0,0,1,1).

Пример 4
div div #example {
    color:red;
}
				
<div>
    <div>
        <span id="example" style="color:green;"></span>
    </div>
</div>
				

Цвет текста в результате будет green, так как инлайновый стиль сильнее обычных. Вес обычного правила - 0,1,0,2, вес инлайнового правила - 1,0,0,0

Правило !important

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

Пример 5
.parent2 .parent1 span.child {color: blue; font-style: italic;}
span {color: red !important; font-style: normal;}
				

Несмотря на то, что специфичность первого правила больше, свойство color все равно применяется из второго правила, так как ему назначен !important, и вес селекторов других правил ему не важен. При этом свойство font-style все равно останется italic, так как вес селекторов первого правила больше, а то же свойство во втором правиле не помечено как особо важное (!important).

Положение в коде также не важно для свойств с !important, если !important для свойства этого элемента назначен всего один. Записав так:

Пример 6
span {color: red !important; font-style: normal;}
.parent2 .parent1 span.child {color: blue; font-style: italic;}
				

получим тоже значение color: red.

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

Пример 7
.parent1 span {color: red !important;}
.parent2 .parent1 span {color: blue !important;}
				

В данном случае применится свойство color: blue, так как вес селекторов его правила больше.

Пример 8
.parent2 .parent1 span {color: blue !important;}
.parent1 span {color: red !important;}
				

Опять же применится свойство color:blue, так как специфичность правила выше, и последовательность правил в таком случае не имеет значения.

Если же вес правил равен:

Пример 9
span {color: blue !important;}
span {color: red !important;}
				

Применится то, что идет последним.

Пример 10
div div #example {
    color:red !important;
}
				
<div>
    <div>
        <span id="example" style="color:green;"></span>
    </div>
</div>
				

В данном случае применится правило color:red !important, так как свойство с правилом !important имеет больший вес чем инлайновые стили, не имеющие такого правила.

Пример 11
div div #example {
    color:red !important;
}
				
<div>
    <div>
        <span id="example" style="color:green; !important"></span>
    </div>
</div>
				

Здесь сработает инлайновое правило color:green !important, так как инлайновые свойства с правилом !important имеют самый большой возможный вес.

Приоритетность наследуемых стилей

Важно отметить, что вес стилей, наследуемых элементами от родителей, всегда равен нулю, его легко перебить с помощью обычного селектора тэга, например a или div, даже, если в правиле, назначенном родителю, будет !important.

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

Пример 12
#parent {color: red;}
span {color: green;}
				

или

#parent {color: red;}
* {color: green;}
				
<div id="parent">
	<span></span>
</div>
				

В обоих случаях к span'у применяется color: green, так как любое правило перебивает вес наследуемых свойств.

Это справедливо даже если стили заданы родителю элемента непосредственно через атрибут style, и даже с правилом !important, их вес по отношению к дочерним элементам все равно будет равняться нулю.

Пример 13
span {color: green;}
				
<div style=”color: red !important;”>
	<span></span>
</div>
				

или

* {color: green;}
				
<div style=”color: red !important;”>
	<span></span>
</div>
				

Результат: в обоих случаях у span'а сработает свойство color: green.

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

Добавить комментарий
Ваше имя (Обязательно)
Ваш e-mail (Обязательно)
Ваш комментарий
Что это? Всатвить код: Link CSS HTML Javascript PHP SQL
Чтобы добавить в комментарий ссылку, стили, разметку или скрипт, оберните его в соответствующий тег с помощью этих кнопок, например [CSS].my-class{margin:0}[/CSS]. Вы можете создать теги обертки с помощью кнопок и вписать туда свой код, или же написав код, выделить его и нажать на кнопку тега, это обернет ваш код в желаемый тег.