В CSS есть чёткие правила, по которым браузер решает, какое правило применить. Это и есть каскад плюс специфичность.
Что такое каскад
Каскад — это просто «порядок сверху вниз». Если у двух правил одинаковая сила (одинаковая специфичность), победит то, которое написано ниже в коде.
Пример:
p { color: blue; } p { color: red; }
У обоих правил селектор одинаковый (p), специфичность равна. Работает каскад: второе правило ниже → цвет текста будет красный.
Это самое простое правило: при равной силе побеждает последний.
Что такое специфичность
Специфичность — это «вес» селектора. Браузер не просто смотрит, кто ниже, а сначала проверяет, у кого селектор «сильнее».
Грубый подсчёт «веса» (для понимания, без формул):
- селектор по тегу (
p,div) — слабый; - селектор по классу (
.card,.btn) — средний; - селектор по ID (
#main) — сильный; - inline‑стили (
style="...") — очень сильный.
Если у одного правила вес больше, оно победит даже если написано выше.
Пример 1: класс сильнее тега
p { color: blue; } /* тег — слабый */ .special { color: red; } /* класс — сильнее */
<p class="special">Текст</p>
Цвет будет красный, несмотря на то, что правило с p стоит первым. Класс «тяжелее» тега.
Пример 2: ID сильнее класса
.special { color: red; } /* класс */ #main p { color: green; } /* ID + тег → ещё сильнее */
<div class="content"> <p>Текст</p> </div>
Цвет будет зелёный. Селектор #main p имеет ID, поэтому он побеждает класс .special.
Пример 3: комбинация селекторов увеличивает вес
div p { color: orange; } /* тег + тег */ .content p { color: purple; } /* класс + тег → тяжелее */
<div class="content"> <p>Текст</p> </div>
Цвет фиолетовый. .content p сильнее, чем div p, потому что класс добавляет вес.
Чем больше «кусочков» в селекторе (классы, ID, вложенность), тем он тяжелее. Но не стоит специально делать селекторы «очень тяжёлыми» ради победы — потом их сложно переопределить.
Порядок, в котором браузер всё сравнивает
Когда стилей много, браузер действует по шагам:
- Происхождение и важность. Сначала смотрит, нет ли правила с
!important. Если есть — оно почти всегда побеждает (но злоупотреблять им не надо). Также учитывает стили браузера, пользовательские стили и т.п. - Специфичность. Если
!importantнет, сравнивает «вес» селекторов. Побеждает более специфичный. - Каскад (порядок в коде). Если специфичность одинаковая, побеждает правило, которое написано ниже.
Частый кейс: почему твой стиль не работает
Ты пишешь:
.btn { background: red; }
А кнопка остаётся синей. Скорее всего, где‑то есть правило вроде:
#header .btn { background: blue; }
Селектор #header .btn содержит ID, он тяжелее, чем просто .btn. Поэтому синий цвет побеждает.
Как исправить без «наращивания веса»:
- Переместить своё правило ниже (если специфичность такая же).
- Сделать селектор чуть точнее, но не слишком тяжёлым. Например:
.page-buttons .btn { background: red; }, если это логично по структуре. - Не ставить ID на каждый элемент и не делать цепочки вида
#main #content .box .item— такие селекторы потом почти невозможно переопределить без!important.
Пример с inline‑стилями
.text { color: green; }
<p class="text" style="color: orange;">Текст</p>
Цвет будет оранжевый. style="..." — это почти самый сильный вариант. Он перебивает обычные классы и теги.
Поэтому inline‑стили используют редко: их тяжело поддерживать и почти невозможно переопределить через обычный CSS.
Шпаргалка по приоритету (от самого сильного к слабому)
- Стили с
!important(если они из того же источника). - Inline‑стили (
style="..."). - Селекторы с ID.
- Селекторы с классами, атрибутами, псевдоклассами.
- Селекторы по тегам и псевдоэлементам.
- Универсальный селектор
*(почти без веса).
И при равном весе побеждает то, что написано ниже.
Ещё один пример целиком
CSS:
p { color: blue; } /* 1 */ .text { color: red; } /* 2 */ #content p { color: green; } /* 3 */
HTML:
<div id="content"> <p class="text">Текст</p> </div>
Какой цвет? Зелёный. У #content p есть ID — он самый специфичный, поэтому побеждает и тег, и класс, даже если они написаны ниже.
Практический совет
- Держи специфичность низкой и ровной. Лучше
.cardи.card-highlight, чем#main .wrapper .content .card. - Если стиль «не применяется», сначала проверь:
- нет ли более специфичного селектора выше или ниже;
- не перебивает ли его inline‑стиль;
- не стоит ли где‑то
!important; - правильно ли написан селектор (точка для класса, решётка для ID).
