EasyCode365EasyCode365

Специфічність, наслідування і каскад

Коли ти створюєш сайт, ти пишеш багато CSS-правил. Іноді два правила намагаються по-різному стилізувати той самий HTML-елемент.

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

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

Що означає каскад

Каскад — це система, яку браузер використовує, щоб вирішити, яке CSS-правило застосувати, коли правила конфліктують.

Браузер дивиться на всі відповідні правила і ставить такі питання:

  • Чи позначене одне правило як важливіше?
  • Чи один селектор є більш специфічним?
  • Якщо правила рівні, яке з них іде пізніше?
Можна редагувати
<p class="intro">Ласкаво просимо на мій сайт!</p>

<style>
  p {
    color: blue;
  }

  .intro {
    color: green;
  }
</style>

Абзац зелений, бо .intro більш специфічний, ніж p.

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

Порядок правил: пізніші правила можуть перемогти

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

Можна редагувати
<button class="button">Натисни</button>

<style>
  .button {
    background-color: blue;
    color: white;
  }

  .button {
    background-color: red;
  }
</style>

Кнопка червона, бо друге правило .button іде пізніше.

Це корисно, коли ти підключаєш власний CSS після стилів бібліотеки. Якщо твій селектор має таку саму силу, твоє пізніше правило може перемогти.

Якщо стиль не з'являється на екрані, перевір, чи інше правило нижче у файлі не перезаписує його.

Специфічність: деякі селектори сильніші

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

Можна редагувати
<h2 id="main-title" class="title">Моя стаття</h2>

<style>
  #main-title {
    color: blue;
  }

  .title {
    color: orange;
  }
</style>

Заголовок синій, бо селектор ID сильніший за селектор класу.

Намагайся тримати селектори простими. Дуже сильні селектори може бути складно перезаписати пізніше.

Проста шкала специфічності

Не потрібно запам'ятовувати складну математику. Для початківців достатньо цієї простої шкали:

  • Селектори елементів, як p, h1 і button, найслабші.
  • Селектори класів, як .card і .nav-link, сильніші.
  • Селектори ID, як #header, сильніші за класи.
  • Inline-стилі, написані в HTML через style="", сильніші за звичайні правила зі CSS-файлу.
Можна редагувати
<div id="hero" class="banner">Привіт</div>

<style>
  #hero {
    background-color: yellow;
  }

  .banner {
    background-color: blue;
  }
</style>

Фон жовтий, бо #hero сильніший за .banner.

Використовуй селектори елементів для базових стилів. Використовуй селектори класів для повторно використовуваних стилів. Рідко використовуй селектори ID для стилізації, бо їх важко перезаписувати.

Уникай inline-стилів для звичайного оформлення сторінки. Вони корисні в особливих випадках, але роблять CSS складнішим у підтримці.

Наслідування: деякі стилі передаються вниз

Наслідування означає, що батьківський елемент може передавати деякі CSS-властивості своїм дочірнім елементам.

Властивості, пов'язані з текстом, часто наслідуються. Приклади: color, font-family і іноді font-size.

Можна редагувати
<div class="card">
  <h2>Ласкаво просимо</h2>
  <p>Це <em>чудовий</em> день.</p>
</div>

<style>
  .card {
    color: blue;
    font-family: Arial, sans-serif;
  }
</style>

Заголовок, абзац і текст em використовують синій колір та шрифт Arial, бо наслідують ці стилі від .card.

Поширений приклад — задати основний шрифт для елемента body.

Лише читання

Тоді більшість тексту на сторінці використовує цей шрифт без повторення правила всюди.

Коли наслідування може плутати початківців

Не кожна CSS-властивість наслідується.

Текстові властивості зазвичай наслідуються. Властивості макета і блоку зазвичай ні.

Можна редагувати
<div class="message">
  <p>Цей абзац знаходиться всередині блока.</p>
</div>

<style>
  .message {
    border: 1px solid black;
    color: blue;
  }
</style>

Текст абзацу стає синім, бо color наслідується.

Але абзац не отримує власну рамку. Рамка належить лише .message.

Це добре. Якби рамки наслідувалися, кожен вкладений елемент малював би власну рамку, і сторінка швидко стала б хаотичною.

Приклад конфліктних правил

Ось прямий конфлікт, де два правила націлені на одне посилання.

Можна редагувати
<a href="#" id="special-link" class="nav-link">Головна</a>

<style>
  .nav-link {
    color: green;
  }

  #special-link {
    color: deeppink;
  }
</style>

Посилання рожеве, бо #special-link — це селектор ID.

Правило .nav-link правильне, але селектор класу слабший за селектор ID.

Що робить !important

!important — це спеціальне ключове слово, яке ставить декларацію попереду звичайних декларацій.

Можна редагувати
<p id="unique-text" class="text">Прочитай це.</p>

<style>
  p.text {
    color: red !important;
  }

  #unique-text {
    color: blue;
  }
</style>

Абзац червоний, бо червона декларація використовує !important.

Без !important переміг би селектор ID.

Коли не використовувати !important

Не використовуй !important лише тому, що CSS не працює.

Це може на мить виправити екран, але часто створює складнішу проблему пізніше. Якщо тобі знову потрібно буде перезаписати це правило, може здатися, що треба додати ще один !important.

Перед використанням перевір:

  • Чи є інший селектор більш специфічним?
  • Чи є інше правило, написане пізніше?
  • Чи можна використати зрозуміліший клас?
  • Чи можна прибрати непотрібний селектор ID?

Коли !important може бути прийнятним

Є рідкісні випадки, коли !important може бути доречним.

Один приклад — маленький utility-клас, який завжди має виконувати одну дію:

Лише читання

Інший приклад — перезапис стилів сторонніх інструментів, які ти не можеш редагувати.

Навіть тоді використовуй !important обережно і тримай його ізольованим.

Типові помилки початківців

  • Думати, що порядок правил завжди перемагає. Для звичайних правил специфічність перевіряється перед порядком.
  • Додавати !important занадто швидко замість того, щоб знайти справжній конфлікт.
  • Використовувати важкі селектори на кшталт #main-nav ul li a.active для простих стилів.
  • Очікувати, що кожна властивість наслідується. Рамки, відступи, padding і фони зазвичай не наслідуються.
  • Використовувати селектори ID для повторно використовуваних стилів. Класи зазвичай легше підтримувати.

Міні-завдання

Подивись на цей HTML і CSS:

Можна редагувати
<h3 class="heading" style="color: blue;">Новини</h3>

<style>
  h3.heading {
    color: orange;
  }

  .heading {
    color: green;
  }
</style>

Якого кольору буде h3 на екрані?

Відповідь: він буде синім, бо inline-стиль сильніший за звичайні правила зі CSS-файлу.

Короткий тест

Питання 1: Який селектор сильніший: клас чи ID?

Відповідь: Селектор ID сильніший за селектор класу.

Питання 2: Якщо два селектори класу націлені на той самий елемент і задають різні кольори, який переможе?

Відповідь: Якщо обидва селектори мають однакову силу, перемагає той, що написаний пізніше.

Питання 3: Чи властивість border автоматично наслідується від батька до дитини?

Відповідь: Ні. Рамки не наслідуються за замовчуванням.

Малий виклик

Цей абзац має мати червоний фон, але зараз він зелений. Зроби правило .alert сильнішим за #content p без використання !important.

Можна редагувати
<div id="content">
  <p class="alert">Попередження: збережи свою роботу!</p>
</div>

<style>
  #content p {
    background-color: green;
  }

  /* Виправ цей селектор */
  .alert {
    background-color: red;
  }
</style>

Один можливий варіант:

Лише читання

Це перемагає, бо поєднує селектор ID із селектором класу, тому є більш специфічним, ніж #content p.

Підсумок

Специфічність, наслідування і каскад

  • Каскад — це спосіб, яким браузер вирішує, яке CSS-правило перемагає.
  • Порядок правил має значення, коли відповідні правила мають однакову силу.
  • Специфічність — це вага селектора.
  • Селектори ID сильніші за селектори класів, а селектори класів сильніші за селектори елементів.
  • Наслідування передає деякі текстові стилі від батьків до дітей.
  • !important ставить декларацію попереду звичайних правил, але його варто уникати більшість часу.