Опубликовано: 24.10.2021

Селекторы стилевых правил

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

Каждое стилевое правило состоит из двух частей: селектора (selector) и блока объявлений (declaration block). Свойства, устанавливаемые стилевым правилом, перечислены в блоке объявлений. Селектор же, предваряющий блок объявлений, позволяет точно определить, на какие элементы или группы элементов веб-документа распространяется данное правило.

Стилевое правило

На сегодняшний день спецификацией CSS определено несколько видов селекторов. Рассмотрим их более подробно.

Базовые виды селекторов

Универсальный селектор

Универсальный селектор (universal selector) позволяет задать общее правило для всех элементов веб-страницы, независимо от типа этих элементов. Для записи такого селектора в CSS используется символ «звёздочка» («*»). Например, чтобы указать, что текст в любом элементе документа должен выводиться серым цветом и быть представлен семействами шрифта sans-serif, можно записать следующее стилевое правило:

* {
  color: grey;
  font-family: Helvetica, Verdana, sans-serif;
}

Однако если использовать универсальный селектор так, как это показано в примере выше, можно столкнуться с одним довольно неприятным моментом. Дело в том, что установка правила для всех элементов на странице может занять достаточно продолжительное время (ведь элементов на странице много). И страница в момент установки такого правила просто зависнет на несколько секунд, что явно подпортит впечатление о сайте.

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

Селекторы типа

Селектор типа (type selector) определяет тип элементов документа, к которым будет применено указанное правило. В качестве селекторов данного вида используются имена тегов. Так, например, чтобы задать цвет и размер символов для заголовков 1-ого уровня, можно записать следующее правило:

h1 {
  color: blue;
  font-size: 32px;
}

Селекторы классов

Упростить установку каких-то особых стилей для отдельных элементов одного типа или, наоборот, одинаковых стилей разнотипным элементам позволяет используемый в HTML универсальный атрибут CLASS. Установить правило для элементов, отнесённых к определённому классу, можно с помощью селектора класса (class selector), который представляет собой имя класса элементов, записанное после символа «точка» («.»).

Например, если необходимо визуально выделить из текста статьи один абзац, его нужно просто отнести к определённому классу:

<p class="attention">Внимание! Материал содержит
  информацию о товарах, употребление которых может
  навредить вашему здоровью.</p>

А в таблице стилей записать правило для данного класса:

.attention {
  padding: 10px 20px;
  border: 3px double #ff8c00;
  color: #ff8c00;
  font-style: italic;
}

После применения этого правила в браузере наш абзац будет выглядеть следующим образом:

Пример оформления абзаца

Селекторы идентификаторов

Для организации навигации внутри документа, а также для обращения к элементам документа из скриптов, в открывающих или единственных тегах элементов довольно часто используется универсальный атрибут ID. Установить стилевое правило для таких элементов позволяет селектор идентификатора (ID selector), который представляет собой идентификатор элемента, записанный после символа «решётка» («#»).

Пример записи селектора идентификатора:

/* скрываем меню до наступления события click */
#floatMenu {
  display: none;
}

Селекторы атрибутов

Установить правило для элементов, содержащих в открывающем или единственном теге определённый атрибут, позволяет селектор атрибута (attribute selector), который представляет собой имя атрибута, записанное в квадратных скобках. Например, изменить вид курсора для элементов, содержащих атрибут TITLE (то есть имеющих всплывающую подсказку), можно с помощью следующего правила:

[title] {
  cursor: help;
}

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

  • [атрибут="значение"] — задать правило для элементов, у которых данный атрибут имеет строго указанное значение;
  • [атрибут^="подстрока"] — задать правило для элементов, у которых значение данного атрибута начинается с указанной подстроки;
  • [атрибут$="подстрока"] — задать правило для элементов, у которых значение данного атрибута заканчивается указанной подстрокой;
  • [атрибут*="подстрока"] — задать правило для элементов, у которых значение данного атрибута содержит указанную подстроку;
  • [атрибут~="подстрока"] — задать правило для элементов, у которых значение данного атрибута содержит указанную подстроку. Однако при этом учитываются только подстроки, отделённые от прочего содержимого пробелами. То есть под действие правила с селектором [title~="один"] попадёт элемент, у которого title="один и два", но не попадёт элемент, у которого title="один, два", так как с указанной подстрокой в значении соседствует запятая;
  • [атрибут|="подстрока"] — задать правило для элементов, у которых значение данного атрибута совпадет с подстрокой, либо начинается с указанной подстроки, за которой следует символ «тире» («-»). То есть под действие правила с селектором [lang|="en"], например, попадут и элементы с атрибутом lang="en", и элементы с атрибутом lang="en-us".

Селекторы атрибутов очень удобно использовать, например, при оформлении ссылок. С помощью селектора [target="_blank"] можно установить особое оформление для внешних ссылок (ведь такие ссылки обычно делают открывающимися в новом окне). С помощью селектора [href^="http:"] можно выделить ссылки, ведущие на сайты без SSL-сертификата. Если же мы хотим проинформировать пользователя о формате открываемого документа, можно воспользоваться селекторами [href$=".pdf"], [href$=".doc"] и им подобными (см. пример ниже).

[href$=".pdf"] {
  /* фоновый рисунок для ссылок данного типа */
  background: url(images/logo-pdf.png) left center no-repeat;
  /* отступ слева для текста ссылки */
  padding-left: 24px;
}

[href$=".doc"] {
  background: url(images/logo-word.png) left center no-repeat;
  padding-left: 24px;
}

[href$=".txt"] {
  background: url(images/logo-txt.png) left center no-repeat;
  padding-left: 24px;
}

В браузере это будет отображено так:

Оформление ссылок на различные форматы документов

В качестве фоновых рисунков к ссылкам в данном примере используются мелкие картинки ( ), для которых отключен режим повторения. А чтобы текст не закрывал фоновый рисунок, с помощью свойства padding-left установлен необходимый отступ слева (см. пример CSS-кода выше).

Группировка селекторов

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

h1 {
  color: blue;
  font-weight: bold;
}

.special {
  color: blue;
  font-weight: bold;
}

#comment-block {
  color: blue;
  font-weight: bold;
}

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

h1, .special, #comment-block {
  color: blue;
  font-weight: bold;
}

Примечание: Спецификацией допускается вставка пробела до и/или после запятой, причём наличие пробела между группируемыми селекторами не является обязательным требованием. Но надо заметить, что более естественно смотрится запись, когда запятая ставится сразу после селектора, а пробел делается после запятой.

Для удобства чтения исходного кода будет даже лучше записывать каждый селектор, входящий в группировку, с новой строки:

h1,
.special,
#comment-block {
  color: blue;
  font-weight: bold;
}

Составные селекторы

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

С помощью составных селекторов можно, например, уточнить параметры для элементов разного типа, но относящихся к одному классу:

/* стили, общие для класса NOTE */
.note {
  border: 1px double #ccc;
  box-shadow: 3px 3px 2px #ccc;
  font-size: 0.94em;
}

/* отступы для элементов P класса NOTE */
p.note {
  padding: 20px 7px 20px 30px;
}

/* отступы для элементов DIV класса NOTE */
div.note {
  padding: 5px 7px 5px 30px;
}

Примечание: В составном селекторе допустим только один селектор типа или универсальный селектор. В последовательности селекторов эти селекторы должны располагаться первыми.

В следующем примере HTML-кода элемент <div> принадлежит одновременно к трём классам: block-image, aligncenter и size-full.

<div class="block-image aligncenter size-full">
  <img src="images/figure1.gif" alt="Фото 1">
</div>

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

.block-image.size-full.aligncenter {
  margin: 10px;
}

Контекстные селекторы

Установить правила для элементов, используя расположение этих элементов в структуре HTML-документа, позволяют контекстные селекторы (иногда их ещё называют селекторами отношений). Записываются такие селекторы с использованием четырёх символов-комбинаторов: символа пробела, символа «больше» («>»), символа «плюс» («+») и символа «тильда» («~»).

Селектор вида A B позволяет установить правило для всех элементов B, вложенных в элемент A, независимо от уровня вложения. Другими словами, он позволяет выбрать все элементы B, являющиеся потомками элемента A.

Элементы B являющиеся потомками элемента A

Селектор вида A>B позволяет установить правило для всех элементов B, непосредственно вложенных в элемент A. Другими словами, он позволяет выбрать все элементы B, являющиеся дочерними элементу A.

Элементы B являющиеся дочерними элементами A

Селектор вида A~B позволяет установить правило для всех элементов B, следующих в исходном коде за элементом A и находящихся на том же уровне вложенности (то есть родительский элемент и у элемента A, и у элементов B должен быть общий).

Сестринские элементы B следующие за A

Селектор вида A+B позволяет установить правило для элемента B, следующего в исходном коде непосредственно за элементом A (то есть родительский элемент и у элемента A, и у элемента B должен быть общий).

Сестринский элемент B следующий за A

Рассмотрим несколько конкретных примеров использования контекстных селекторов. Допустим, у нас имеется имеется некий многоуровневый маркированный список:

<ul>
  <li>Элемент 1-ого уровня
  <ul>
    <li>Элемент 2-ого уровня
    <ul>
      <li>Элемент 3-его уровня</li>
      <li>Элемент 3-его уровня</li>
    </ul></li>
    <li>Элемент 2-ого уровня
    <ul>
      <li>Элемент 3-его уровня</li>
      <li>Элемент 3-его уровня</li>
    </ul></li>
  </ul></li>
  <li>Элемент 1-ого уровня
  <ul>
    <li>Элемент 2-ого уровня
    <ul>
      <li>Элемент 3-его уровня</li>
      <li>Элемент 3-его уровня</li>
    </ul></li>
    <li>Элемент 2-ого уровня
    <ul>
      <li>Элемент 3-его уровня</li>
      <li>Элемент 3-его уровня</li>
    </ul></li>
  </ul></li>
</ul>

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

ul {
  color: black;
  list-style-type: circle;
}

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

Многоуровневый маркированный список

Но если мы хотим установить разные виды маркеров для разных уровней списка, то нам потребуется к вышеприведённому правилу добавить пару уточняющих правил с контекстными селекторами:

ul {
  color: black;
  list-style-type: circle;
}
ul li li {
  /* вид маркеров для элементов 2-ого уровня */
  list-style-type: disc;
}

ul li li li {
  /* вид маркеров для элементов 3-ого уровня */
  list-style-type: square;
}

Другой и более компактный вариант:

ul {
  color: black;
  list-style-type: circle;
}
ul ul {
  list-style-type: disc;
}

ul ul ul {
  list-style-type: square;
}

Результатом работы данных правил в браузере будет список следующего вида:

Многоуровневый маркированный список

Цвет маркеров в этих списках по умолчанию совпадает с цветом текстового содержимого. Чтобы сделать маркеры и текст разных цветов, все текстовые строки дополнительно потребуется поместить в элементы SPAN:

<ul>
  <li><span>Элемент 1-ого уровня</span>
  <ul>
    <li><span>Элемент 2-ого уровня</span>
    <ul>
      <li> <span>Элемент 3-его уровня</span></li>
      <li><span>Элемент 3-его уровня</span></li>
    </ul></li>
    <li><span>Элемент 2-ого уровня</span>
    <ul>
      <li><span>Элемент 3-его уровня</span></li>
      <li><span>Элемент 3-его уровня<span></li>
    </ul></li>
  </ul></li>
  <li><span>Элемент 1-ого уровня</span>
  <ul>
    <li><span>Элемент 2-ого уровня</span>
    <ul>
      <li><span>Элемент 3-его уровня</span></li>
      <li><span>Элемент 3-его уровня</span></li>
    </ul></li>
    <li><span>Элемент 2-ого уровня</span>
    <ul>
      <li><span>Элемент 3-его уровня</span></li>
      <li><span>Элемент 3-его уровня</span></li>
    </ul></li>
  </ul></li>
</ul>

А также создать ещё одно отдельное правило для текстовых строк:

ul {
  /* цвет маркеров списка*/
  color: blue;
  list-style-type: circle;
}
ul ul {
  list-style-type: disc;
}

ul ul ul {
  list-style-type: square;
}

/* цвет текстового содержимого*/
ul span {
  color: black;
}

В результате получим список следующего вида:

Многоуровневый маркированный список

А теперь оставим в покое наш список, и рассмотри несколько иные ситуации.

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

/* отступ сверху для каждого элемента,
   вложенного в элемент DIV класса NOTE */
div.note * {
  margin-top: 25px;
}

Данное правило прекрасно сработает для всех вложенных элементов, но… в случае с любыми списками — маркированными, нумерованными или списками определений — картина получится не совсем красивая. Ведь у нас не только сами списки (то есть элементы OL, UL или DL) получат увеличенный отступ сверху, но и элементы этих списков (то есть элементы LI, DT или DD):

Увеличенный отступ между элементами

Поэтому правило придётся немного подкорректировать в зависимости от ситуации. Например, если списки в данном элементе DIV являются единственными многократно вложенными элементами, можно воспользоваться другим контекстным селектором:

/* отступ сверху для дочерних элементов
   элемента DIV класса NOTE */
div.note > * {
  margin-top: 25px;
}

И тогда список в браузере получит более привычный вид:

Увеличенный отступ между элементами

Если же в данном элементе DIV присутствуют и другие многократно вложенные элементы, то лучше использовать первое правило, дополнив его дополнительным правилом для списков (см. пример ниже). Причём в этом дополнительном правиле необходимо учесть все разновидности списков, которые могут присутствовать внутри контейнера DIV, а также степени и варианты их вложения. Так, например, нижеприведённое правило учитывает, что в элементе DIV класса NOTE могут присутствовать только многоуровневые нумерованные и маркированные списки и их комбинации:

/* отступ сверху для каждого элемента,
   вложенного в элемент DIV класса NOTE */
div.note * {
  margin-top: 25px;
}

/* отступы между элементами любых многоуровневых
   списков, вложенных в элемент DIV класса NOTE */
div.note li, div.note li ol, div.note li ul  {
  margin-top: 10px;
}

Псевдоэлементы

Установить стиль для какой-то определённой части HTML-элемента, не меняя стиль HTML-элемента в целом, позволяют так называемые псевдоэлементы. Псевдоэлемент CSS — это ключевое слово, которое добавляется к селектору для указания конкретной части элемента, на которую будет распространяться данное правило. При написании такое ключевое слово отделяется от селектора двумя двоеточиями («::»). Например, полная запись селектора, устанавливающего правило для первой строки каждого абзаца, будет следующей: p::first-line.

Примечание: Поскольку в первой версии стандарта CSS псевдоэлементы было принято отделять от селектора одним двоеточием, многие браузеры и по сей день в целях совместимости поддерживают оба синтаксиса (selector:pseudo-element и selector::pseudo-element) для тех псевдоэлементов, которые были приняты в ранних версиях стандарта.

На сегодняшний день наиболее часто используются следующие псевдоэлементы:

  • ::first-line — позволяет установить правило для первой строки элемента;
  • ::first-letter — позволяет установить правило для первой буквы элемента;
  • ::selection — позволяет установить правило для текста, выделенного пользователем с помощью мыши или клавиш курсора;
  • ::after — применяется для вставки назначенного контента после содержимого элемента. Данный псевдоэлемент работает совместно со стилевым свойством content, которое определяет содержимое для вставки;
  • ::before — применяется для вставки назначенного контента до содержимого элемента. Данный псевдоэлемент работает совместно со стилевым свойством content, которое определяет содержимое для вставки.

Рассмотрим пару практических примеров.

Например, если мы хотим воспроизвести у себя на странице что-то похожее на буквицу (то есть выделить цветом и размером первую букву первого абзаца), то можно использовать следующее правило:

h1 + p::first-letter {
  color: #ff6347;
  font-size: 200%;
}

Bид такой буквицы в браузере будет следующим:

Результат в браузере

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

Изменить вид текста, выделенного пользователем, позволяет псевдоэлемент ::selection. По умолчанию такой текст в браузерах обычно «подсвечивается» синим цветом фона (см. рис. ниже), что может не устраивать веб-разработчика.

Стандартное оформление выделения в тексте

Изменить цвет «подсветки» можно, например, с помощью следующего правила:

::selection {
  color: gold;
  background-color: red;
}

И выделение в браузере примет следующий вид:

Оформление выделения в тексте

Псевдоклассы

Кроме псевдоэлементов в языке CSS используется также большое количество ключевых слов, называемых псевдоклассами. Псевдоклассы CSS — это ключевые слова, которые добавляются к селекторам для указания состояния, положения, статуса и других параметров элементов, на которые необходимо распространить правила. При написании такие ключевые слова отделяются от селектора двоеточием («:»). Например, полная запись селектора, устанавливающего правило для элемента формы, получившего фокус, будет следующей: input:focus.

Вот неполный список псевдоклассов, используемых в CSS:

  • :active — позволяет установить правило для кнопки или ссылки, активированной пользователем. (При использовании мыши «активация» обычно начинается, когда пользователь нажимает левую кнопку мыши в момент нахождения указателя над объектом);
  • :disabled — позволяет установить правило для любого отключенного элемента, то есть для элемента, в открывающем или единственном теге которого присутствует атрибут disabled;
  • :first-child — позволяет установить правило для элемента, являющегося первым в группе сестринских элементов;
  • :focus — позволяет установить правило для ссылки или элемента формы, получившего фокус при переходе к нему с помощью клавиши Tab или «нажатии» на данный элемент с помощью мыши;
  • :hover — позволяет установить правило для любого элемента, над которым находится указатель мыши;
  • :last-child — позволяет установить правило для элемента, являющегося последним в группе сестринских элементов;
  • :link — позволяет установить правило для непосещённых ссылок (то есть ссылок, о которых отсутствует информация в истории браузера);
  • :not(селектор_исключаемого_элемента) — позволяет установить правило для всех элементов, за исключением элемента, указанного в аргументе;
  • :nth-child(аргумент) — позволяет установить правило для элемента по его номеру в группе сестринских элементов. Аргумент может быть числом, ключевым словом odd или even, либо числовым выражением в виде An+B, где A и B — целые числа, а n — счётчик, автоматически принимающий целые неотрицательные значения от 0 и больше: 0, 1, 2, 3, …;
  • :only-child — позволяет установить правило для элемента, являющегося единственным дочерним элементом у своего родителя;
  • :visited — позволяет установить правило для посещённых ссылок (то есть ссылок, о которых имеется информация в истории браузера).

Рассмотрим несколько примеров использования псевдоклассов на практике.

Допустим, у нас имеется таблица с какими-то результатами, которую необходимо оформить особым образом. Для создания особых стилей оформления вынесем её в отдельный класс — results:

<table class="results">
  <tr>
    <td></td>
    <td>Янв</td>
    <td>Фев</td>
    <td>Мар</td>
    <td>Апр</td>
    <td>Май</td>
    <td>Июн</td>
  </tr>
  <tr>
    <td>Иванов П.И.</td>
    <td>16</td>
    <td>34</td>
    <td>62</td>
    <td>74</td>
    <td>57</td>
    <td>16</td>
  </tr>
  <tr>
    <td>Николаев С.А.</td>
    <td>4</td>
    <td>69</td>
    <td>72</td>
    <td>56</td>
    <td>47</td>
    <td>12</td>
  </tr>
  <tr>
    <td>Петров Г.А.</td>
    <td>7</td>
    <td>73</td>
    <td>79</td>
    <td>34</td>
    <td>86</td>
    <td>10</td>
  </tr>
  <tr>
    <td>Сидоров А.С.</td>
    <td>23</td>
    <td>34</td>
    <td>88</td>
    <td>53</td>
    <td>103</td>
    <td>22</td>
  </tr>
</table>

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

Вид таблицы в браузере

Чтобы раздвинуть таблицу на ширину родительского элемента, увеличить величину внутреннего отступа в ячейках и изменить вид выравнивания в ячейках с результатами (то есть во всех ячейках, кроме ячеек заголовочных и ячеек первого столбца), зададим три правила:

.results {
  width: 100%;
}

.results th,
.results td {
  padding: 4px;
}

.results td:not(td:first-child) {
  text-align: right;
}

Результат на экране:

Вид таблицы в браузере

Ещё три дополнительных правила помогут нам создать особый стиль для заголовочных ячеек (за исключением первой из них) и ячеек первого столбца таблицы:

.results th:not(th:first-child),
.results td:first-child {
  color: white;
  background-color: #8a2be2;
}

.results th:not(th:first-child) {
  border-radius: 6px 6px 0 0;
}

.results td:first-child {
  border-radius:  6px 0 0 6px;
}

В результате работы всех этих правил наша таблица станет выглядеть уже значительно лучше:

Вид таблицы в браузере

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

/* фон для чётных строк */
.results tr:nth-child(even) td:not(td:first-child) {
  background-color: #f0f0f0;
}

/* фон для нечётных строк */
.results tr:nth-child(odd) td:not(td:first-child) {
  background-color: #d0d0d0;
}

/* скругляем правый нижний угол */
.results tr:last-child td:last-child {
  border-radius: 0 0 6px 0;
}

Итоговый результат:

Вид таблицы в браузере

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

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

Например, у нас имеется какой-то абзац, который принадлежит к классу content и ему присвоен идентификатор first-paragraph (см. пример ниже).

<p id="first-paragraph" class="content">Lorem ipsum
  dolor sit amet, consectetuer adipiscing elit, sed
  diem nonummy nibh euismod tincidunt ut lacreet dolore
  magna aliguam erat volutpat. Ut wisis enim ad minim
  veniam, quis nostrud exerci tution.</p>

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

p {
  text-indent: 50px;
  color: black;
}

#first-paragraph {
  padding-left: 30px;
  color: teal;
}

.content {
  font-size: 10px;
  color: gray;
}

Все объявления из этих правил, не противоречащие друг другу (то есть свойства text-indent, padding-left и font-size), будут применены к вышеприведённому абзацу. А вот из трёх объявлений, устанавливающих цвет текстового содержимого (свойство color), браузер выберет и применит только одно. И в своём выборе он будет руководствоваться специфичностью правил.

Специфичность правила (selector specificity) — это уровень его приоритета (весомость) в противоречивых ситуациях. Вес правила определяется видом базовых селекторов, а также их количеством, если это составные или контекстные селекторы.

Согласно спецификации при расчёте специфичности правила используются три группы оценок (A, B, C), которые формируются следующим образом:

  • каждый селектор типа или псевдоэлемент даёт единицу в группу C;
  • каждый селектор класса, атрибута или псевдокласс (кроме :not()) даёт единицу в группу B;
  • каждый селектор идентификатора даёт единицу в группу A;
  • универсальный селектор на оценки не влияет.

Таким образом, правила из вышеприведённого примера будут иметь следующие оценки:

p { ... }                    /*  A=0 B=0 C=1  */  

#first-paragraph { ... }     /*  A=1 B=0 C=0  */

.content { ... }             /*  A=0 B=1 C=0  */

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

Если у нескольких правил специфичность всё-таки окажется одинаковой, то к элементу будет применено объявление, стоящее в исходном коде последним.

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

* { ... }                     /*  A=0 B=0 C=0  */  

li { ... }                    /*  A=0 B=0 C=1  */

ul li { ... }                 /*  A=0 B=0 C=2  */

ul ol+li { ... }              /*  A=0 B=0 C=3  */

h1+*[rel=up] { ... }          /*  A=0 B=1 C=1  */

ul ol li.red { ... }          /*  A=0 B=1 C=3  */

li.red.level { ... }          /*  A=0 B=2 C=1  */

#par1:not(.content) { ... }   /*  A=1 B=1 C=0  */

Примечание: Псевдокласс :not() при расчёте специфичности не учитывается, но учитываются селекторы, используемые в нём в качестве аргумента. Например, в контекстном селекторе div:not(.outer) p две единицы в оценку группы C дадут селекторы типа div и p, и одну единицу в оценку группы B даст селектор класса .outer. Присутствие же самого псевдокласса :not() на оценки не повлияет.

div:not(.outer) p { ... }     /*  A=0 B=1 C=2  */

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

Объявлениям из атрибута style также присваивается высший уровень приоритета, но приоритет объявлений с модификатором !important является более высоким.

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

Другие статьи по схожей тематике

Раздел: CSS