Перейти до основного вмісту

Каскад стилів

Каскадування - це механізм, який керує кінцевими значеннями властивостей елемента, якщо до нього застосовується кілька CSS-правил.

  • Якщо до елемента застосовується кілька правил, їх властивості комбінуються
  • Якщо правила містять однакові властивості з різними значеннями, то вони конфліктують
/* Яким буде колір тексту абзаців? */
p {
color: blue;
background-color: orange;
}

p {
color: teal;
}

Для того щоб зібрати фінальні стилі елемента і вирішити конфлікти значень властивостей, браузер використовує два механізми: специфічність і наслідування.

Специфічність селектора​

Для кожного CSS-правила браузер обчислює специфічність (вагу) селектора. Якщо до елементу потрібно застосувати властивості з різних правил, та існують конфліктуючі (однакові) властивості, використовується значення властивості з правила з найбільш високою специфічністю селектора.

Значення специфічності складається з чотирьох рангів, важливість яких збільшується справа наліво.

Формула специфічності

Селектори 4-го рангу​

Кожен селектор елемента і псевдоелемента додає одиницю до четвертого рангу.

<article>
<h1>Lorem ipsum dolor sit amet</h1>
<p>
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Obcaecati commodi,
veritatis nihil alias iste odit similique sit eius optio veniam, impedit
cumque fuga facere labore quo id necessitatibus quaerat rerum.
</p>
<a href="">Читати далі...</a>
</article>

Колір тексту абзацу буде помаранчевим, тому що специфічність другого правила вище.

/* Специфічність - 0 0 0 1 */
p {
color: green;
}

/* ✅ Специфічність - 0 0 0 2 */
article > p {
color: orange;
}

Селектори 3-го рангу​

Кожен селектор класу, атрибута і псевдокласу додає одиницю до третього рангу.

<article class="post">
<h1 class="post-title">Lorem ipsum dolor sit amet</h1>
<p>
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Obcaecati commodi,
veritatis nihil alias iste odit similique sit eius optio veniam, impedit
cumque fuga facere labore quo id necessitatibus quaerat rerum.
</p>
<a href="" class="post-link">Читати далі...</a>
</article>

Колір тексту заголовка буде помаранчевим, бо специфічність третього правила вище.

/* Специфічність - 0 0 1 0 */
.post-title {
color: green;
}

/* Специфічність - 0 0 1 1 */
.post > h1 {
color: red;
}

/* ✅ Специфічність - 0 0 2 0 */
.post > .post-title {
color: orange;
}

Колір тексту посилання буде коричневим, тому що специфічність п'ятого правила вище.

/* Специфічність - 0 0 0 1 */
a {
color: green;
}

/* Специфічність - 0 0 1 0 */
.post-link {
color: orange;
}

/* Специфічність - 0 0 1 1 */
a.post-link {
color: blue;
}

/* Специфічність - 0 0 2 0 */
.post > .post-link {
color: red;
}

/* ✅ Специфічність - 0 0 2 1 */
.post > a.post-link {
color: brown;
}

Селектори 2-го рангу​

Кожен селектор ідентифікатора додає одиниць до другого рангу.

<article class="post">
<h1 class="post-title" id="title">Lorem ipsum dolor sit amet</h1>
<p>
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Obcaecati commodi,
veritatis nihil alias iste odit similique sit eius optio veniam, impedit
cumque fuga facere labore quo id necessitatibus quaerat rerum.
</p>
<a href="" class="post-link">Читати далі...</a>
</article>

Колір тексту заголовка буде помаранчевим, бо специфічність другого правила вище.

/* Специфічність - 0 0 1 0 */
.post-title {
color: green;
}

/* ✅ Специфічність - 0 1 0 0 */
#title {
color: orange;
}

Селектори 1-го рангу​

Вбудовані стилі додають одиницю до першого рангу, мають найвищу специфічність, і їх неможливо перевизначити через CSS.

<!-- Специфічність такого стилю - 1 0 0 0 -->
<p style="color: green;">
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Obcaecati commodi,
veritatis nihil alias iste odit similique sit eius optio veniam, impedit
cumque fuga facere labore quo id necessitatibus quaerat rerum.
</p>

Однакова специфічність​

Якщо специфічність однакова, перемагає правило, розташоване нижче в коді.

/* Три селектори елемента з однаковою специфічністю */
a {
color: teal;
}

a {
color: brown;
}

/* Оскільки це правило стоїть нижче, до всіх посилань застосується помаранчевий колір тексту */
a {
color: orange;
}

Уникаємо специфічності​

Якщо селектор виглядає як A > B > C + X Y, варто задуматися. Чим простіший селектор, тим менше проблем зі специфічністю. Візьміть собі за правило використовувати селектори класу. Атрибут class не тільки допомагає уникнути проблем зі специфічністю, але й підвищує читабельність HTML-розмітки.

Перший підхід - це присвоєння класу загальному блоку-батькові та використання селекторів дитини і нащадка.

<article class="post">
<h1>Lorem ipsum dolor sit amet</h1>
<p>
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Obcaecati commodi,
veritatis nihil alias iste odit similique sit eius optio veniam, impedit
cumque fuga facere labore quo id necessitatibus quaerat rerum.
</p>
<a href="">Читати далі...</a>
</article>

Такий CSS добре працює, коли розмітка проста. Але зі зростанням складності розмітки блоку, зручна стилізація по селекторам тегу стає неможливою. Наприклад, якщо в пості буде 5 посилань, а не одне, точково вибрати якесь посилання не вийде або селектор буде занадто складний.

.post {
/* Стилі статті */
}

.post > h1 {
/* Стилі заголовка */
}

.post > p {
/* Стилі тексту */
}

.post > a {
/* Стилі посилання */
}

.post > a:hover {
/* Стилі посилання при ховері */
}

Другий підхід - це додавання описових класів блоку-батькові і тегами всередині нього.

<article class="post">
<h1 class="title">Lorem ipsum dolor sit amet</h1>
<p class="text">
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Obcaecati commodi,
veritatis nihil alias iste odit similique sit eius optio veniam, impedit
cumque fuga facere labore quo id necessitatibus quaerat rerum.
</p>
<a class="link" href="">Читати далі...</a>
</article>

Такий CSS непогано масштабується і підтримується. Це відправна точка для написання хорошого CSS. Проте, з ростом складності розмітки можуть бути невеликі проблеми зі специфічністю.

.post {
/* Стилі статті */
}

.post > .title {
/* Стилі заголовка */
}

.post > .text {
/* Стилі тексту */
}

.post > .link {
/* Стилі посилання */
}

.post > .link:hover {
/* Стилі посилання при ховері */
}

Третій підхід полягає у встановленні дуже специфічних класів блоку-батькові та кожному тегу всередині нього за принципом імя_батька-імя_дитини.

<article class="post">
<h1 class="post-title">Lorem ipsum dolor sit amet</h1>
<p class="post-text">
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Obcaecati commodi,
veritatis nihil alias iste odit similique sit eius optio veniam, impedit
cumque fuga facere labore quo id necessitatibus quaerat rerum.
</p>
<a href="" class="post-link">Читати далі...</a>
</article>

За такого підходу використовуються прості селектори класу, не потрібно думати про специфічність. Такий CSS добре масштабується і підтримується. В сучасній розробці під час написання стилів використовуються варіації цього підходу.

.post {
/* Стилі статті */
}

.post-title {
/* Стилі заголовка */
}

.post-text {
/* Стилі тексту */
}

.post-link {
/* Стилі посилання */
}

.post-link:hover {
/* Стилі посилання при ховері */
}
Корисно

Не варто обмежувати себе у виборі лише одного підходу. Усі три методи іменування розмітки класами і написання стилів можна використовувати разом, залежно від ситуації.

Ключове слово !important​

Специфічність правила можна підвищити за допомогою ключового слова !important, додавши його після значення властивості.

<p class="text" id="text-id">
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Obcaecati commodi,
veritatis nihil alias iste odit similique sit eius optio veniam, impedit
cumque fuga facere labore quo id necessitatibus quaerat rerum.
</p>

Значення такої властивості приорітетніше від усіх інших, і колір тексту абзацу буде помаранчевий.

p {
color: orange !important;
}

p#text-id.text {
color: blue;
}
Увага

Вкрай не рекомендується використовувати !important в сучасній розробці. Єдиний оптимальний випадок - це перевизначення значення властивості, якщо відсутній прямий доступ до файлу зі стилями, наприклад стиль з бібліотеки.

Наслідування властивостей​

Генетичне наслідування звично бачити в житті. Наприклад, у високих батьків найчастіше високі діти, часто передається колір волосся тощо. Дещо подібне існує і в CSS. Якщо встановити зелений колір тексту батькові, то, якщо будь-яке правило не перевизначить це значення, колір тексту всіх його нащадків також буде зеленим.

Наслідування - це механізм, за допомогою якого значення певних властивостей передаються від предка його нащадкам. Наслідуються переважно властивості оформлення тексту, наприклад колір. Це зручно, оскільки не потрібно ставити повторювані стилі для кожного нащадка окремо.

<article class="post">
<h1>Популярне за цей місяць</h1>
<p>
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Obcaecati commodi,
veritatis nihil alias iste odit similique sit eius optio veniam, impedit
cumque fuga facere labore quo id necessitatibus quaerat rerum.
</p>
<a href="">Читати далі...</a>
</article>

Зробимо весь текст посту зеленого кольору.

.post {
color: green;
}

В інструментах розробника, на вкладці Styles внизу побачимо наслідування для абзацу і заголовка.

Наслідування властивості color

В житті не всі атрибути батьків передаються дітям. Те саме і в CSS, що не кожна властивість за замовчуванням наслідується нащадками. Фактично, якби всі властивості були успадковані, ефект був би аналогічний відсутності наслідування взагалі, і довелося б написати дуже багато CSS для скидання стилів наслідуваних від батька, щоб перевизначити цю поведінку.

Винятки​

Не всі елементи наслідують значення властивостей від предків. Наприклад, посилання не наслідує колір тексту.

<article class="post">
<h1>Популярне за цей місяць</h1>
<p>
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Obcaecati commodi,
veritatis nihil alias iste odit similique sit eius optio veniam, impedit
cumque fuga facere labore quo id necessitatibus quaerat rerum.
</p>
<a href="" class="post-link">Читати далі...</a>
</article>

Якщо необхідно, щоб у пості воно була такого ж кольору, що і весь текст, можна використовувати спеціальне значення inherit для властивості color, щоб не дублювати колір у двох місцях.

.post {
color: green;
}

.post-link {
color: inherit;
}
Корисно

Значення inherit говорить браузеру про те, що необхідно наслідувати значення властивості від предка. Для кольору краще використовувати значення currentColor (поточний колір).

Колір тексту сторінки​

Для того щоб задати базовий (домінантний) колір тексту всього документа, створюємо правило для тегу <body> і додаємо властивість color. Цей колір буде наслідуваний усім текстовим контентом, крім посилань.

body {
color: #2a2a2a;
}