Загрузка...

Вложенность (nesting) в CSS

Переменные дали имена вашим значениям. calc и компания их вычислили. Nesting упорядочивает селекторы, которые этими значениями пользуются: держите заголовок, кнопку и hover-стили карточки внутри .card, а не повторяйте имя родителя по всему файлу.

Вложите дочерний селектор

Пишите правило внутри другого. Вложенный селектор класса или типа присоединяется как потомок родителя (комбинатор-пробел), если вы не скажете иначе через &:

Card styles nested under one parent

css
.card {
padding: 1.25rem;
border-radius: 0.75rem;
background: var(--surface, #fff);

.title {
margin: 0 0 0.5rem;
font-size: 1.25rem;
}

.body {
color: var(--muted, #444);
line-height: 1.5;
}
}

Браузер разворачивает это в .card .title и .card .body. Вы по-прежнему получаете обычные селекторы потомков — nesting это сахар для структуры и локальности, а не новая модель сопоставления.

Родительский селектор &

Используйте &, когда вложенное правило должно цепляться к тому же элементу, что и родитель — псевдоклассы, псевдоэлементы или дополнительный класс на родителе:

Hover and modifier on the same element

css
.button {
display: inline-flex;
padding: 0.6rem 1.1rem;
border: 0;
border-radius: 0.5rem;
background: var(--brand, #2563eb);
color: #fff;

&:hover {
background: var(--brand-hover, #1d4ed8);
}

&:focus-visible {
outline: 2px solid var(--brand, #2563eb);
outline-offset: 2px;
}

&.is-primary {
background: var(--brand-strong, #1e40af);
}
}

&:hover значит .button:hover. &.is-primary значит .button.is-primary. Без & голое :hover { } — недопустимый nesting в нативном CSS: & делает привязку явной.

Комбинаторы с &

Ставьте комбинатор после &, когда нужен прямой потомок, сосед или другая явная связь — не просто пробел потомка:

Child and adjacent patterns with &

css
.nav {
display: flex;
gap: 0.75rem;

& > .item {
padding: 0.35rem 0.6rem;
}

& > .item + .item {
border-inline-start: 1px solid #ddd;
}

/* same as nesting .item without & — descendant */
.badge {
font-size: 0.75rem;
}
}

& > .item → .nav > .item. Вложенный .badge без & → .nav .badge. Выбирайте намеренно: случайные глубокие потомки — типичный запах nesting.

Вложите @media рядом с компонентом

Можно вкладывать at-rules вроде @media внутрь style-правила, чтобы брейкпоинты жили рядом с компонентом, который они меняют:

Responsive tweaks beside the component

css
.hero {
padding: 2rem 1.25rem;

h1 {
font-size: clamp(1.75rem, 1.2rem + 2vw, 2.75rem);
}

@media (min-width: 48rem) {
padding: 3rem 2rem;

h1 {
max-width: 20ch;
}
}
}

После развёртывания media query по-прежнему оборачивает объявления для .hero (и .hero h1). Свяжите это с токенами и clamp() из прошлых уроков Modern Toolkit — nesting только переносит правила.

Паттерны nesting одним взглядом

📊 Шпаргалка нативного nesting

Вы пишете Это значит Когда использовать
.card { .title { } } .card .title Стилизовать потомка под компонентом
.btn { &:hover { } } .btn:hover Псевдокласс на том же элементе
.btn { &.big { } } .btn.big Дополнительный класс на том же элементе
.nav { & > a { } } .nav > a Явный комбинатор прямого потомка
.box { @media (…) { } } Media query, ограниченный селекторами этого правила Держать брейкпоинты с компонентом

Держите вложенность мелкой

Два-три уровня обычно остаются читаемыми. Более глубокие деревья возвращают проблему «пирамиды селекторов» из мира Sass: тяжёлые diff’ы, выше specificity и стили, которые имеют смысл только внутри одного гигантского родителя. Предпочитайте ясный корень компонента (.card, .nav) и вкладывайте состояния и близких детей — не всю страницу.

Связка компонента: tokens + nest + состояния

Реалистичный фрагмент связывает последние три идеи toolkit, не повторяя уроки calc или переменных:

Panel with tokens, nested parts, and a state

css
.panel {
--panel-pad: 1rem;
padding: var(--panel-pad);
border: 1px solid #e5e7eb;
border-radius: 0.75rem;

.heading {
margin: 0 0 0.5rem;
font-weight: 600;
}

.actions {
display: flex;
gap: calc(var(--panel-pad) / 2);
margin-block-start: var(--panel-pad);
}

&.is-compact {
--panel-pad: 0.5rem;
}

@media (max-width: 36rem) {
.actions {
flex-direction: column;
}
}
}

Токены по-прежнему custom properties; calc по-прежнему выводит отступ; nesting держит heading, actions, компактное состояние и правку для маленького экрана в одном месте.

Попробуйте сами

  1. Возьмите плоские правила .card {}, .card .title {}, .card .meta {} и перепишите их с nesting под .card.
  2. Добавьте &:hover на .link, чтобы цвет менялся только у ссылки (не у вложенного span).
  3. Вложите @media (min-width: 40rem) внутрь .sidebar, чтобы расширить padding — в DevTools проверьте развёрнутые селекторы.
  4. Превратите ошибочно вложенный :hover { } (без &) в &:hover { } и убедитесь, что он валиден.
  5. Ограничьте беспорядочный трёхуровневый nest двумя уровнями, вынеся внутренний блок в свой класс.

Частые ошибки

  • Писать :hover { } вложенно без & — неверно или не то, что вы имели в виду; используйте &:hover
  • Ожидать, что голое .child значит .parent.child — для этого нужен &.child
  • Слепо копировать Sass-хаки &__element для BEM — нативный nesting следует грамматике селекторов CSS
  • Вкладывать пять уровней «потому что можно» — страдают читаемость и specificity
  • Думать, что nesting заменяет var() или calc() — он только группирует селекторы и at-rules

Итог

  • Вкладывайте дочерние селекторы, чтобы стили компонента оставались локальными; по умолчанию они разворачиваются в потомков
  • Используйте & для состояний того же элемента (:hover, .is-active) и явных комбинаторов
  • Вкладывайте @media рядом с компонентом, который настраиваете
  • Держите nest мелким; nesting — это структура, не токены и не математика
  • Дальше в Modern Toolkit: container queries — стили от размера родителя, а не только viewport

🧠 Проверьте Свои Знания

Готов к Началу

Проверьте Свои Знания

Бросьте себе вызов с помощью этой интерактивной викторины и узнайте, насколько хорошо вы понимаете тему

❓
6
Вопросы
🎯
70%
Для Прохождения
♾️
∞
Время
🔄
∞
Попытки

📝 Инструкции

  • Внимательно прочитайте каждый вопрос
  • Выберите лучший ответ на каждый вопрос
  • Вы можете пересдавать тест столько раз, сколько захотите
  • Ваш прогресс будет показан вверху