CSS: какой цвет текста при конфликте селекторов
Есть шаблон HTML и CSS кода:
<html>
<head>
<style>
#element {
color: red;
}
.element {
color: blue;
}
div.element {
color: yellow;
}
div.element {
color: magenta;
}
div.element {
color: magenta;
}
div.element {
color: magenta;
}
div.element {
color: magenta;
}
</style>
</head>
<body>
<div id="element" class="element">
Таким образом, постоянное
</div>
</body>
</html>
Какой будет цвет у текста «Таким образом, постоянное»?
Разбор по шагам
Рассматриваемый элемент — это div с атрибутами id="element" и class="element", значит одновременно подходят селекторы #element, .element и div.element.
Среди подходящих правил выбирается то, у которого выше специфичность селектора; при разных специфичностях порядок в CSS (кто ниже написан) не меняет победителя.
У #element специфичность выше, чем у .element и div.element, поэтому итоговый цвет текста будет red.
<div id="element" class="element">
Таким образом, постоянное
</div>
div.element действительно конфликтуют между собой, но они «соревнуются» только внутри своей группы одинаковой специфичности и не могут обойти правило с #element, потому что у #element выше специфичность.Теория: специфичность
Специфичность — это правило приоритета, по которому браузер определяет «вес» селектора и выбирает, какое значение свойства применить при конкурирующих правилах.
В учебной форме специфичность удобно считать как тройку ID - CLASS - TYPE, где ID — количество #id, CLASS — количество классов/атрибутов/псевдоклассов, TYPE — количество селекторов по тегу и псевдоэлементов.
Таблица специфичности для данной задачи:
| Селектор | Что выбирает | Специфичность (ID-CLASS-TYPE) | Цвет из правила |
|---|---|---|---|
#element | элемент с id="element" | 1-0-0 | red |
.element | элементы с class="element" | 0-1-0 | blue |
div.element | div с class="element" | 0-1-1 | yellow / magenta (зависит от порядка) |
Ключевое сравнение: 1-0-0 (ID) «старше», чем 0-1-1 (класс + тег), потому что сравнение идёт слева направо, и более высокий разряд ID побеждает независимо от остальных.
/* Специфичность (ID-CLASS-TYPE) */
#element { color: red; } /* 1-0-0 */
.element { color: blue; } /* 0-1-0 */
div.element { color: yellow; } /* 0-1-1 */
div.element { color: magenta; } /* 0-1-1 (то же самое) */
div.element { color: magenta; } /* 0-1-1 */
div.element { color: magenta; } /* 0-1-1 */
div.element { color: magenta; } /* 0-1-1 */
#id часто делают переопределения сложнее: чтобы «перебить» #id, обычно требуется либо другой #id (или несколько), либо !important, а это ухудшает поддерживаемость стилей.Теория: каскад и порядок
Каскад — это общий механизм выбора значений CSS-свойств (кто «победит» при конкурирующих стилях), где учитываются важность (!important), происхождение стилей и другие шаги; специфичность — один из ключевых шагов этого механизма.
Если конкурирующие правила находятся в одном месте (например, в одном блоке <style>) и имеют одинаковую специфичность, применяется правило, объявленное позже (ниже по коду).
В данной задаче важно разделить два конфликта:
- Конфликт между
div.element { color: yellow; }и последующимиdiv.element { color: magenta; }
У них одинаковая специфичность0-1-1, поэтому среди них победит самое последнее по порядку —magenta. - Конфликт между победителем из группы
div.elementи правилом#element { color: red; }
У#elementспецифичность1-0-0, она выше, значит итоговый цвет становитсяred, даже если ниже в CSS написаны другие правила с меньшей специфичностью.
Небольшая схема принятия решения для этого примера:
Шаг 1. Найти все правила, которые подходят элементу:
- #element
- .element
- div.element (несколько раз)
Шаг 2. Сравнить специфичность:
- #element -> 1-0-0 (самая высокая)
- div.element -> 0-1-1
- .element -> 0-1-0
Шаг 3. Выбрать самое специфичное:
- Побеждает #element -> color: red
Кратко: элемент подходит под #element, .element и div.element, но правило #element { color: red; } имеет наибольшую специфичность, поэтому текст будет красным (red).