Перейти к содержанию

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

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

CSS подкаст

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

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

1
<button class="branding">Hello, Specificity!</button>

1
2
3
4
5
6
7
button {
    color: red;
}

.branding {
    color: blue;
}

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

Специфичность — это один из четырех отдельных этапов каскада, который рассматривался в предыдущем модуле, на the cascade.

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

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

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

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

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

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

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

1
2
3
* {
    color: red;
}

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

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

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

1
2
3
div {
    color: red;
}

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

1
2
3
::selection {
    color: red;
}

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

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

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

1
2
3
.my-class {
    color: red;
}

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

1
2
3
:hover {
    color: red;
}

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

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

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

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

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

Селектор ID

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

1
2
3
#myID {
    color: red;
}

Атрибут inline style

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

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

!important правило

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

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

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

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

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

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

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

1
2
3
a {
    color: red;
}

Обратитесь к одному из классов в этом правиле, теперь он имеет 11 баллов специфичности:

1
2
3
a.my-class {
    color: green;
}

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

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

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

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

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

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

Визуализация специфичности

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

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

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

В качестве примера можно привести следующий селектор 0-4-1:

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

Прагматическое увеличение специфичности

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

1
2
3
4
5
6
7
.my-button {
    background: blue;
}

button[onclick] {
    background: grey;
}

В HTML это выглядит следующим образом:

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

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

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

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

1
2
3
4
5
6
7
.my-button.my-button {
    background: blue;
}

button[onclick] {
    background: grey;
}

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

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

При совпадении показателей специфичности побеждает новейший экземпляр.

Оставим пока пример с кнопкой и изменим CSS следующим образом:

1
2
3
4
5
6
7
.my-button {
    background: blue;
}

[onclick] {
    background: grey;
}

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

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

1
2
3
4
5
6
7
[onclick] {
    background: grey;
}

.my-button {
    background: blue;
}

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

Ресурсы

Источник: Specificity

Комментарии