HTML/CSSMiddleTechnical
Что такое каскад CSS и как работает наследование?
Каскад — алгоритм выбора победившего CSS-объявления по origin, специфичности и порядку. Наследование — передача вычисленного значения от родителя потомку для наследуемых свойств (color, font, line-height).
Каскад: как браузер выбирает победителя
Когда несколько правил претендуют на одно свойство одного элемента, браузер проходит по приоритетам по убыванию:
- Origin и важность:
!importantпользователя >!importantавтора > normal автора > normal пользователя > браузерные дефолты. - Слои (
@layer): объявленные позже слои имеют приоритет (если origin одинаковый). - Специфичность: inline-стиль (1,0,0,0) > ID (0,1,0,0) > класс/атрибут/псевдокласс (0,0,1,0) > тег/псевдоэлемент (0,0,0,1).
- Порядок в источнике: при равной специфичности побеждает последнее объявление.
/* Специфичность: 0,0,1,1 — класс + тег */
p.note { color: gray; }
/* Специфичность: 0,1,0,0 — ID */
#content { color: black; }
/* Специфичность: 0,0,1,0 — класс */
.highlight { color: gold; }
/* Для <p id="content" class="note highlight">:
Побеждает #content (наибольшая специфичность) → color: black */
Наследование: не все свойства передаются вниз
Наследование — отдельный механизм. Если для элемента нет явного объявления и нет cascade-победителя, браузер смотрит на родителя — но только для наследуемых свойств.
Наследуются: color, font-family, font-size, font-weight, line-height, letter-spacing, text-align, visibility, cursor.
НЕ наследуются: width, height, margin, padding, border, background, display, position.
body {
font-family: Inter, sans-serif;
color: #172033;
line-height: 1.5;
}
/* Все дочерние элементы наследуют font-family, color, line-height */
/* Но background и padding каждый задаёт сам */
.card {
background: #fff;
padding: 24px;
/* color: #172033 — унаследован от body */
}
.card strong {
/* color: #172033 — унаследован, но можно переопределить */
font-weight: 700;
}
Ключевые слова: inherit, initial, unset, revert
.reset-link {
color: inherit; /* взять у родителя, даже если свойство не наследуется */
margin: initial; /* вернуть к браузерному умолчанию */
all: unset; /* сбросить всё — наследуемые наследуют, остальные → initial */
color: revert; /* вернуть к значению из user-agent stylesheet */
}
Подводные камни
- !important разрывает каскад. Злоупотребление
!importantделает код непредсказуемым: единственный способ перебить важный стиль — ещё более специфичный!important. В проектах с legacy-кодом это часто образует «специфичность-гонку». - Специфичность не складывается через запятую.
.a, .b { color: red }— это два отдельных правила с специфичностью (0,0,1,0) каждое, а не одно комбинированное. Порядок побеждает при равенстве. - Наследование не работает через display: contents.
display: contentsубирает бокс элемента из рендеринга, но не из DOM. Наследование проходит через него, однако computed values для самого элемента ведут себя неожиданно. - CSS custom properties всегда наследуются. Переменные (
--color) наследуются по умолчанию, даже если обычное свойство не наследуется. Это мощный инструмент для тем, но неожиданная переменная от далёкого предка может перетереть локальное значение. - @layer меняет приоритет без изменения специфичности. Стиль в слое с низким приоритетом проиграет стилю без слоя, даже если имеет более высокую специфичность. Это ломает интуицию при смешении layered и unlayered стилей.
- Порядок
@importи<link>имеет значение. При одинаковой специфичности победит последнее объявление в порядке подключения. Ленивая загрузка стилей через JS может изменить этот порядок в runtime и сломать стили. - font-size наследует вычисленное, а не declared значение. Если родитель имеет
font-size: 1.2em, ребёнок наследует абсолютное computed значение в пикселях, а не1.2em. Вложенные em-единицы не умножаются бесконечно.
Common mistakes
- Смешивать «каскад и наследование CSS» с похожим механизмом без критерия выбора.
- Игнорировать риск: неверно оценить границы применения темы «каскад и наследование CSS» и получить хрупкое решение.
- Показывать только синтаксис и не объяснять поведение в runtime или сборке.
What the interviewer is testing
- Объясняет как браузер выбирает итоговое значение свойства.
- Показывает на примере, как работает: каскад выбирает победившее объявление, а наследование передает computed value от родителя только для наследуемых свойств; эти механизмы похожи, но решают разные задачи.
- Называет production-нюанс и граничный случай для темы «каскад и наследование CSS».