CSS: спецификация и каскад

Недавний опрос вызвал бурные обсуждения, из которых можно сделать вывод, что у некоторых разработчиков наблюдается пробел в знаниях CSS.

Не будем зацикливаться на раздувании споров. Вместо этого углубимся в теорию и проведем время с пользой.

Пример под рукой

Используем тот же пример, который использовался в опросе. Я заменил color на background и использовал более приятные цвета.

Вот, что получилось:

HTML

<main>
    <div class="red blue"></div>
    <div class="blue red"></div>
</main>

CSS

.red {
    background: #c23616;
}

.blue {
    background: #4b7bec;
}






/* Нерелевантный вид и стили */
body {
    height: 100vh;
    margin: 0;
    display: grid;
    place-items: center;
}

main {
    padding: 2rem;
}

div {
    width: 180px;
    height: 180px;
    border-radius: 5px;
}

div + div {
    margin-top: 10px;
}

Как видите, оба блока синего цвета. Но почему? Причина этого заключается в том, что и .red, и .blue имеют одинаковый уровень специфичности. Поэтому браузер выбирает последний стиль в CSS-коде. В примере – это .blue.

Если поменять местами объявления классов в CSS, то получим следующее:

HTML

<main>
    <div class="red blue"></div>
    <div class="blue red"></div>
</main>

CSS

.blue {
    background: #273c75;
}

.red {
    background: #c23616;
}





/* Нерелевантный вид и стили */
body {
    height: 100vh;
    margin: 0;
    display: grid;
    place-items: center;
}

main {
    padding: 2rem;
}

div {
    width: 180px;
    height: 180px;
    border-radius: 5px;
}

div + div {
    margin-top: 10px;
}

Так как .red был объявлен после .blue, то блоки стали красными. Логика браузера при каскадной сортировке выглядит следующим образом: он перемещается вниз по таблице стилей, пока не обнаружит самое специфичное правило. Приведенные выше правила обладают равной специфичностью, поэтому объявление .red после .blue приводит к окрашиванию блоков в красный цвет.

Базовое введение в спецификацию

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

Используем селектор ID

Селектор повышает приоритетность правила в спецификации. id будет приоритетнее, чем class. Поэтому в следующем примере новое правило #green станет специфичнее, чем .red и .blue, несмотря на расположение в CSS.

Использование селекторов ID в CSS допустимо. Но лучше привязывать стили к классам, элементам и атрибутам HTML.

Пример:

HTML

<main>
    <div class="red blue" id="green"></div>
    <div class="blue red"></div>
</main>

CSS

.red {
    background: #c23616;
}

.blue {
    background: #4b7bec;
}

#green {
    background: #20bf6b;
}





/* Нерелевантный вид и стили */
body {
    height: 100vh;
    margin: 0;
    display: grid;
    place-items: center;
}

main {
    padding: 2rem;
}

div {
    width: 180px;
    height: 180px;
    border-radius: 5px;
}

div + div {
    margin-top: 10px;
}

Добавляем атрибут style

Добавим в первый div атрибут style. Это сделает правило #green менее специфичным, потому что атрибуты style приоритетнее любого правила в CSS, кроме !important.

В следующем примере я установил фиолетовый цвет для #green в атрибуте style. В результате он становится специфичнее всех остальных стилей (в том числе определенных в .red и .blue).

Пример:

HTML

<main>
    <div class="red blue" id="green" style="background: #a55eea"></div>
    <div class="blue red"></div>
</main>

CSS

.red {
    background: #c23616;
}

.blue {
    background: #4b7bec;
}

#green {
    background: #20bf6b;
}


body {
    height: 100vh;
    margin: 0;
    display: grid;
    place-items: center;
}

main {
    padding: 2rem;
}

div {
    width: 180px;
    height: 180px;
    border-radius: 5px;
}

div + div {
    margin-top: 10px;
}

Добавляем !important

Последнее правило, рассматриваемое в данной статье – !important. Этот модификатор выигрывает в любом случае.

Я добавлю !important в класс .red. В результате все блоки станут красными. Так как !important имеет наибольший приоритет. Но использовать этот модификатор необходимо с умом. Ведь из-за его важности ни один элемент не может быть специфичнее, чем !important.

Пример:

HTML

<main>
    <div class="red blue" id="green" style="background: #a55eea"></div>
    <div class="blue red"></div>
</main>

CSS

.red {
    background: #c23616 !important;
}

.blue {
    background: #4b7bec;
}

#green {
    background: #20bf6b;
}





/* Нерелевантный вид и стили */
body {
    height: 100vh;
    margin: 0;
    display: grid;
    place-items: center;
}

main {
    padding: 2rem;
}

div {
    width: 180px;
    height: 180px;
    border-radius: 5px;
}

div + div {
    margin-top: 10px;
}

Заключение

Понимание каскада и спецификации CSS важно. Эти знания помогут вам стать профессиональным веб-разработчиком.

Пожалуйста, оставьте свои мнения по текущей теме статьи. Мы очень благодарим вас за ваши комментарии, дизлайки, отклики, подписки, лайки!

Пожалуйста, оставляйте свои мнения по текущей теме статьи. Мы крайне благодарны вам за ваши комментарии, подписки, отклики, дизлайки, лайки!

Ангелина Писанюкавтор-переводчик статьи «CSS specificity and the cascade»