Специфика

Подкаст CSS – 003: Специфика

Предположим, вы работаете со следующими HTML и CSS:

<button class="branding">Hello, Specificity!</button>
button {
  color: red;
}

.branding {
  color: blue;
}

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

Специфичность — это одна из четырех отдельных стадий каскада, которые были рассмотрены в последнем модуле «Каскад» .

Оценка специфичности

Каждое правило селектора получает оценку. Вы можете думать о специфичности как об общем балле, и каждый тип селектора приносит баллы в счет этого балла. Побеждает селектор, набравший наибольшее количество очков.

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

Оценка каждого типа селектора

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

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

Универсальный селектор ( * ) не имеет специфичности и получает 0 баллов . Это означает, что любое правило, имеющее 1 или более баллов, будет иметь приоритет над ним.

* {
  color: red;
}

Селектор элемента или псевдоэлемента

Селектор элемента (типа) или псевдоэлемента получает 1 балл специфичности .

Выбор типа

div {
  color: red;
}

Селектор псевдоэлементов

::selection {
  color: red;
}

Селектор класса, псевдокласса или атрибута

Селектор класса , псевдокласса или атрибута получает 10 баллов за специфичность .

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

.my-class {
  color: red;
}

Селектор псевдокласса

:hover {
  color: red;
}

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

[href='#'] {
  color: red;
}

Псевдокласс :not() сам по себе ничего не добавляет к вычислению специфичности. Однако селекторы, переданные в качестве аргументов, добавляются к вычислению специфичности.

div:not(.my-class) {
  color: red;
}

Этот образец будет иметь 11 особенностей, поскольку он имеет один селектор типа ( div ) и один класс внутри :not() .

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

Селектор идентификаторов получает 100 баллов специфичности , если вы используете селектор идентификаторов ( #myID ), а не селектор атрибутов ( [id="myID"] ).

#myID {
  color: red;
}

Атрибут встроенного стиля

CSS, примененный непосредственно к атрибуту style HTML-элемента, получает оценку специфичности в 1000 баллов . Это означает, что для того, чтобы переопределить его в CSS, вам придется написать чрезвычайно специфический селектор.

<div style="color: red"></div>

!important правило

Наконец, !important в конце значения CSS получает оценку специфичности в 10 000 баллов . Это высшая специфичность, которую может получить один отдельный предмет.

К свойству CSS применяется правило !important , поэтому все в общем правиле (селектор и свойства) не получает одинаковую оценку специфичности.

.my-class {
  color: red !important; /* 10,000 points */
  background: white; /* 10 points */
}

Проверьте свое понимание

Проверьте свои знания в области оценки специфичности

Какова оценка специфичности a[href="#"] ?

1
Символ a оценивается в 1 балл, а символ [href="#"] — в 10 баллов.
5
Попробуйте еще раз!
11
Символ a оценивается в 1 балл, а символ [href="#"] — в 10 баллов, что дает общий балл 11 баллов .

Специфика в контексте

Специфика каждого селектора, соответствующего элементу, суммируется. Рассмотрим этот пример HTML:

<a class="my-class another-class" href="#">A link</a>

Эта ссылка имеет два класса. Добавьте следующий CSS, и он получит 1 балл специфичности :

a {
  color: red;
}

Ссылайтесь на один из классов в этом правиле, теперь оно имеет 11 особенностей :

a.my-class {
  color: green;
}

Добавьте в селектор другой класс, теперь он имеет 21 специфичность :

a.my-class.another-class {
  color: rebeccapurple;
}

Добавьте атрибут href в селектор, теперь он имеет 31 специфичность :

a.my-class.another-class[href] {
  color: goldenrod;
}

Наконец, добавьте ко всему этому псевдокласс :hover , и селектор получит 41 точку специфичности :

a.my-class.another-class[href]:hover {
  color: lightgrey;
}

Проверьте свое понимание

Проверьте свои знания в области оценки специфичности

Какой из следующих селекторов приносит 21 балл ?

article > section
Элементы оцениваются в 1 балл, в селекторе есть 2 элемента, что дает 2 балла .
article.card.dark
Элементы оцениваются в 1 балл, классы — в 10 баллов, а при наличии 2 классов и 1 элемента этот селектор оценивается в 21 балл .
article:hover a[href]
Элементы оцениваются в 1 балл, псевдоклассы и атрибуты — в 10 баллов, за элементы — 2 балла, а за атрибуты и классы — 20 баллов, поэтому этот селектор стоит 22 балла .

Визуализация специфики

В диаграммах и калькуляторах специфичности специфичность часто визуализируется так:

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

Левая группа — селекторы id . Вторая группа — селекторы классов, атрибутов и псевдоклассов. Последняя группа — селекторы элементов и псевдоэлементов.

Для справки, следующий селектор — 0-4-1 :

a.my-class.another-class[href]:hover {
  color: lightgrey;
}

Проверьте свое понимание

Проверьте свои знания о специфике визуализации

Какой из следующих селекторов равен 1-2-1 ?

section#specialty.dark
Этот селектор отображается как 1-1-1 .
#specialty:hover li.dark
🎉
[data-state-rad].dark#specialty:hover
Этот селектор отображается как 1-3-0 .
li#specialty section.dark
Этот селектор отображается как 1-1-2 .

Прагматичное повышение специфичности

Допустим, у нас есть CSS, который выглядит так:

.my-button {
  background: blue;
}

button[onclick] {
  background: grey;
}

С HTML это выглядит так:

<button class="my-button" onclick="alert('hello')">Click me</button>

Кнопка имеет серый фон, потому что второй селектор получает 11 баллов специфичности ( 0-1-1 ). Это связано с тем, что у него есть один селектор типа ( button ), который составляет 1 балл , и селектор атрибута ( [onclick] ), который составляет 10 баллов .

Предыдущее правило .my-button получает 10 баллов ( 0-1-0 ), поскольку имеет один селектор классов.

Если вы хотите усилить это правило, повторите селектор классов следующим образом:

.my-button.my-button {
  background: blue;
}

button[onclick] {
  background: grey;
}

Теперь кнопка будет иметь синий фон, поскольку новый селектор получает оценку специфичности 20 баллов ( 0-2-0 ).

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

Давайте пока остановимся на примере кнопки и изменим CSS на это:

.my-button {
  background: blue;
}

[onclick] {
  background: grey;
}

Кнопка имеет серый фон, поскольку оба селектора имеют одинаковую оценку специфичности ( 0-1-0 ).

Если вы переключите правила в исходном порядке, кнопка станет синей.

[onclick] {
  background: grey;
}

.my-button {
  background: blue;
}

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

Ресурсы