Xiper

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

Автор: Александр Головко Дата публикации:
Последнее обновление:

Предыдущая статья Наследование: общие сведения

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

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

Как это выглядит

Специфичность представляет собой группу из четырех чисел. Например, 0,0,0,0 или 0,0,1,2.

Как подсчитать специфичность

Специфичность считается по селектору. Правила подсчета очень просты:

  • каждый присутствующий в селекторе идентификатор добавляет к специфичности 0,1,0,0;
  • каждый класс, псевдокласс или атрибут добавляет к специфичности 0,0,1,0;
  • каждый элемент или псевдоэлемент добавляет к специфичности 0,0,0,1;
  • универсальный селектор и комбинаторы не учитываются.

Давай закрепим полученные знания и поупражняемся в расчете специфичности.

p {/*какие-то определения */}
div p {/*какие-то определения */}
p.note {/*какие-то определения */}
form.feedbackForm input[type="text"]  {/*какие-то определения */}
#conten a:hover {/*какие-то определения */}

Превая строка — одинокий селектор типа. Специфичность 0,0,0,1.

Вторая строка — два селектора типа. Специфичность 0,0,0,2.

Теретья строка — селектор типа и класса. Специфичность 0,0,1,1.

Четвертая строка — два селектора типа, один класса и один атрибута. Специфичность 0,0,2,2.

Пятая строка — селектор идентификатора, типа и псевдокласс. Специфичность 0,1,1,1.

Кто победил?

Сравниваются специфичности очень просто. Какое число больше, то определение и выиграло.

Например:
0,0,1,4 больше, чем 0,0,1,2.
0,1,2,0 больше, чем 0,0,2,1.

Учти, что первые (те, которые левее) числа всегда возьмут верх над последующими (более правыми). Они как бы находятся в более старшем разряде.

Например, 0,1,0,0 больше, чем 0,0,8,9.

Если тебе так удобнее, можешь мысленно отбросить запятые и рассматривать предыдущий пример, как 100>89. Только не запутайся, если какой-то из разрядов специфичности будет больше девяти (что может быть при сильно навороченном селекторе). Например, если получилась специфичность 0,1,10,14, запятые отбрасывать нельзя, а то все разряды попутаются.

Специфичность и объявления

Специфичность относится как бы не ко всему правилу в целом, а к каждому конкретному объявлению. Поэтому, может получиться что правило «отработает» не полностью. Например:

<div class="box">Подопытный текст</div>
div {
	color: #0f0;			/* Специфичность 0,0,0,1. */
	font-weight: bold;		/* Специфичность 0,0,0,1. */
}	 
.box {
	font-weight: normal;	/* Специфичность 0,0,1,0. */
}	 

Объявление из строки 2 для элемента <div class="box"> отработает нормально, а объявление из строки 3 будет перебито объявлением из строки 6 (так как у него больше специфичность). Текст внутри нашего div будет зеленым, но не жирным.

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

Интересно знать

Обрати внимание, что специфичность селектора идентификатора (0,1,0,0) всегда выше, чем селектора атрибута (0,0,1,0). Даже если этот атрибут — id! Поэтому:

form.feedback input[id="name"] {
	color: #f00;	/* Специфичность 0,0,2,2. */
}	 
#name {
	color: #0f0;	/* Специфичность 0,1,0,0. - победа! */
}	 

Встроенные стили

По идее, кто-то уже давно должен был спросить, а зачем, собственно, в специфичности самая первая цифра? Ведь мы ее до сих пор никак не использовали!

Все верно. Первая цифра зарезервирована для встроенных стилей. Считается, что их специфичность равна 1,0,0,0. Таким образом, встроенный стиль всегда перебивает стиль заданный во внешней или вложенной таблице стилей. Например:

<div id="box" style="color: #0f0">Этот текст будет зеленым</div>

Даже использовав селектор идентификатора, мы не перебъем встроенный стиль.

div#box {
	color: #00f;	/* Специфичность 0,1,0,1. - маловато */
}	 

Это что же получается? На встроенные стили нет никакой управы?

Не волнуйся. Конечно, есть способ перебить встроенные стили (а заодно и все остальные объявления).

Объявление !important

Если очень нужно, можно пометить какое нибудь объявление, как важное (important). Такое объявление будет считаться заведомо победившим при сравнивании специфичностей. Да, да, в том числе победившем и встроенные стили. Давай немного изменим CSS для предыдущего примера:

div {
	color: #00f !important;	/* важное объявление - сразу победа! */
}	 

Даже слабенький по специфичности (0,0,0,1) селектор типа перебил встроенный стиль, ведь его объявление теперь стало важным!

Детали применения !important хорошо описаны в нашем CSS-справочнике. Если хочешь узнать подробности — перейди по ссылке !important.

Теперь, вооружившись знанием о расчете специфичности можно продолжить изучение наследования в CSS.

Следующая статья — Наследование.