Ви змінюєте колір кнопки, але вона залишається синьою. Додаєте ще один клас, потім ідентифікатор, а наприкінці — !important. Такий ремонт швидко перетворює таблицю стилів на суперечку селекторів. Надійніший підхід — спочатку визначити, на якому кроці каскаду ваше оголошення програло. Специфічність важлива, але вона не є першим і єдиним критерієм.
Спочатку — умови та місце правила
Перевірте, чи селектор узагалі відповідає потрібному елементу, чи завантажився файл і чи виконується умова @media. Далі браузер враховує походження оголошень, їхню важливість та каскадні шари. Лише серед правил, що залишилися на однаковому рівні пріоритету, порівнюють специфічність. Якщо й вона однакова, значення можуть визначати близькість області @scope та порядок оголошень.
Для звичайного проєкту зручно спочатку розібрати простий випадок: ваші власні правила, без анімацій, переходів, вбудованих атрибутів стилю та @scope. У таких межах порядок шарів, специфічність і порядок запису пояснюють більшість повсякденних конфліктів. Це свідома межа прикладу, а не повна заміна алгоритму CSS.
Як читати специфічність
Порівнюйте три колонки зліва направо: ідентифікатори; класи, атрибути й псевдокласи; назви елементів і псевдоелементи. Наприклад, .card .button має вагу 0-2-0, а #checkout .button — 1-1-0. Не перетворюйте ці значення на десяткове число: велика кількість класів не «переноситься» до колонки ідентифікаторів.
Універсальний селектор і комбінатори ваги не додають. Псевдоклас :where() разом зі своїми аргументами має нульову специфічність. Це корисно для базового оформлення компонента: можна точно вказати місце застосування стилю й залишити простий спосіб його перевизначити.
<article class="card">
<button class="button" type="button">Додати до списку</button>
</article>:where(.card) .button { color: #1d4ed8; } /* 0-1-0 */
.button { color: #166534; } /* 0-1-0 */В обох правил однакова вага. У цьому прикладі друге записане пізніше, тому текст буде зеленим. Якщо перший селектор замінити на .card .button, синій колір переможе через вищу специфічність. Переставляння цих двох рядків тоді вже не допоможе.
Домовтеся про шари один раз
Каскадні шари дозволяють відділити базові правила від компонентів і свідомих винятків. Оголосіть їхній порядок на початку головного CSS-файлу. Назви шарів — ваша домовленість усередині проєкту, а не вбудовані категорії браузера.
@layer base, components, overrides;
@layer base {
button { font: inherit; }
}
@layer components {
.button { color: #1d4ed8; padding: .75rem 1rem; }
}
@layer overrides {
.button { color: #166534; }
}Для звичайних авторських оголошень пізніший шар має перевагу над попереднім. Водночас звичайні правила поза шарами мають пріоритет над звичайними правилами всередині шарів. Тому безсистемне додавання «ще одного файлу без шару» може зруйнувати очікуваний порядок. Для оголошень з !important порядок шарів обертається; цей виняток важливо пам’ятати, а не використовувати як основний спосіб компонування стилів.
Не плутайте конфлікт із успадкуванням
Припустімо, контейнер отримав червоний колір через селектор з ідентифікатором, а посилання всередині має власне правило зеленого кольору. Посилання може бути зеленим навіть за дуже простої назви класу. Вага селектора контейнера тут не змагається з вагою селектора посилання: успадковане значення використовується тоді, коли властивість потребує такого успадкування, а не як ще одне правило, що безпосередньо відповідає дочірньому елементу.
Ця відмінність особливо корисна під час налагодження шрифтів. Подивіться, чи значення встановлено на самій кнопці, чи прийшло від її батька. Стандартні стилі елементів форми також можуть пояснювати відмінність. Не збільшуйте специфічність навмання, якщо насправді потрібне свідоме успадкування шрифту або кольору.
Для перевірки тимчасово вимкніть правило в інспекторі й спостерігайте за обчисленим значенням. Робіть це по одній властивості. Якщо одночасно змінити колір, селектор, порядок файлів і шар, ви побачите результат, але не зрозумієте причину виправлення.
Короткий порядок діагностики
- Відкрийте інспектор і знайдіть конкретну властивість, а не весь компонент одразу.
- Перевірте, чи немає помилки в назві властивості або неприйнятного значення.
- Подивіться на переможне правило: файл, шар, специфічність та позначку важливості.
- Приберіть непотрібне підвищення ваги замість дублювання ідентифікаторів.
- Повторіть перевірку для вузького екрана: інша умова медіазапиту може змінювати набір правил.
Після виправлення видаліть тимчасові експерименти. Коментар потрібен там, де лишився свідомий виняток: поясніть обмеження стороннього компонента або причину шару. Так наступний розробник побачить рішення, а не загадковий селектор, який випадково виграв сьогодні.