Вложенность CSS
Стили одного компонента часто разбросаны по нескольким правилам: .card, .card h3, .card:hover. Каждый раз приходится повторять .card. Вложенность (nesting) позволяет писать правила для потомков прямо внутри правила родителя. Раньше для этого нужны были препроцессоры вроде Sass, а с 2023 года вложенность работает в самом CSS во всех современных браузерах.
Правило внутри правила
Вложенное правило пишут внутри фигурных скобок родительского. Оно относится к потомкам родителя — как если бы селекторы стояли через пробел:
<style>
.card {
padding: 12px;
background: lavender;
h3 { margin: 0 0 4px; color: rebeccapurple; }
p { margin: 0; }
}
</style>
<div class="card">
<h3>Анна</h3>
<p>Фронтенд-разработчица</p>
</div>Запись h3 внутри .card равна обычному селектору .card h3.
Символ &
Символ & означает «сам родительский селектор». Он нужен, когда селектор надо приклеить к родителю без пробела — для псевдоклассов и дополнительных классов:
<style>
.btn {
padding: 8px 16px;
border: none;
background: steelblue;
color: white;
&:hover { background: crimson; }
&.big { font-size: 20px; }
}
</style>
<button class="btn">Обычная</button>
<button class="btn big">Большая</button>&:hover превращается в .btn:hover, а &.big — в .btn.big.
Вложенные медиазапросы
@media и @container тоже можно вложить. Тогда все стили элемента — и обычные, и адаптивные — лежат в одном месте:
<style>
.title {
font-size: 18px;
color: seagreen;
@media (min-width: 500px) {
font-size: 28px;
}
}
</style>
<p class="title">На широком окне шрифт крупнее</p>Внутри вложенного медиазапроса свойства пишут сразу, без повторного селектора. Сузьте окно браузера, чтобы пример стал уже 500 пикселей, — заголовок уменьшится.
& в конце
& можно поставить не только в начале. Запись .dark & значит «этот элемент внутри .dark» — удобно, чтобы описать вариант компонента в другом окружении:
<style>
.label {
padding: 4px 8px;
background: gold;
.dark & { background: black; color: gold; }
}
.dark { padding: 8px; background: dimgray; }
</style>
<span class="label">Светлый фон</span>
<div class="dark"><span class="label">Тёмный фон</span></div>Не увлекайтесь
Каждый уровень вложенности удлиняет селектор и повышает его специфичность — силу в каскаде. Глубокие цепочки .page .main .card .title span трудно перебить и легко сломать. Хорошее правило — не больше двух-трёх уровней. Ограничить стили компонентом без роста специфичности помогает правило @scope — урок «Область стилей: @scope».
Запись внутри .card | Что получится |
|---|---|
p | .card p |
&:hover | .card:hover |
&.active | .card.active |
& + & | .card + .card |
.dark & | .dark .card |
Частая ошибка
Псевдокласс без & превращается в селектор потомка. :hover внутри .link означает .link :hover — «любой потомок под курсором», а не сама ссылка:
<style>
.link {
color: steelblue;
:hover { color: crimson; }
}
.ok {
color: steelblue;
&:hover { color: crimson; }
}
</style>
<p><a class="link" href="#">Без &: не краснеет</a></p>
<p><a class="ok" href="#">С &: краснеет при наведении</a></p>Для псевдоклассов и псевдоэлементов всегда пишите & вплотную: &:hover, &::before.