Вложенная структура

Вложенные правила стилей CSS могут сделать ваши таблицы стилей более организованными, удобными для чтения и обслуживания.

Обзор

Теперь, когда вы узнали о селекторах , вы, вероятно, задаетесь вопросом, как лучше организовать их в таблицах стилей. Представьте, что вы применяете стили к элементам раздела «Функции» на вашем сайте. Благодаря вложенности вы можете сгруппировать эти стили внутри правила .feature следующим образом:

.feature {
  button {
    color: blue;
  }

  .link {
    color: red;
  }

  .text {
    font-size: 1.3em;
  }
}

Это было бы то же самое, что написать каждый стиль отдельно:

.feature button {
  color: blue;
}

.feature .link {
   color: red;
}

.feature .text {
   font-size: 1.3em;
}

Вложенность может быть настолько глубокой, насколько необходимо.

.feature {
  .heading {
    color: blue;

    a {
      color: green;
    }
  }
}

Группировка и установление отношений

Вложенность позволяет более лаконично группировать и устанавливать связи между правилами стилей.

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

/* targets headings that are siblings of the .feature element and come immediately after it */
.feature {
  + .heading {
    color: blue;
  }

/* targets all paragraphs that are direct children of the .feature element */
  > p {
    font-size: 1.3em;
  }
}

Определите явные связи с помощью селектора &

Вы также можете использовать селектор & для более чёткого представления вложенных правил стиля. Символ & можно рассматривать как символ, представляющий родительский селектор.

.feature {
 & button {
    color: blue;
  }
}

Это было бы эквивалентно написанию стилей следующим образом:

.feature button {
  color: blue;
}

Когда & требуется

Без & вложенные селекторы будут потомками родительского селектора. Для формирования составных селекторов требуется & .

.feature {
  &:last-child {
    /* Selects the .feature element that is the :last-child, equivalent to .feature:last-child */
  }
   
  & :last-child {
    /* Selects the :last-child inside of a .feature element, equivalent to .feature :last-child */
  }

  &.highlight {
    /* Selects .feature elements that also have a .highlight class, equivalent to .feature.highlight */
  }

  & .highlight {
     /* Selects elements inside of the .feature element with the class .highlight, equivalent to .feature .highlight */
  }
}

Вы также можете изменить контекст и поместить селектор & в конце дочернего селектора или по обе стороны от него.


/* Targets buttons with an adjacent sibling button */
button {
  & + & {
    /* … */
  }
}
img {
  .my-component & {
    /* styles for images inside of `.my-component` ... */
  }
}

В последнем примере мы добавляем стили для изображений внутри элемента с классом .my-component . Это может быть полезно, если вы работаете над проектом, в котором нельзя добавить class или id к элементу.

Вложенность и специфичность

Как и :is() , вложенный селектор принимает специфичность селектора с самой высокой специфичностью в списке селекторов родителя.

#main-header,
.intro {
  & a {
    color: green;
  }
}

.intro a {
  color: blue;
}

Первое правило применяется ко всем ссылкам внутри элементов #main-header и .intro , присваивая им зеленый цвет.

Второе правило пытается переопределить это, чтобы сделать ссылки внутри элемента .intro синими.

Мы можем понять, почему это не работает, если рассмотрим специфику каждого правила.

/* equivalent to :is(#main-header, .intro) a with a specificity of (1, 0, 1) */
#main-header,
.intro {
  & a {
    color: green;
  }
}

/* lower specificity of (0, 1, 1) */
.intro a {
  color: blue;
}

Поскольку первое правило содержит id в списке селекторов, а вложенные правила используют специфичность селектора с наибольшей специфичностью, его специфичность выше, чем у второго правила. Ссылки отображаются зелёным цветом даже для a , не находящихся внутри элемента с селектором #main-header .

Недопустимая вложенность

Подобно :is() , селектор вложенности не может представлять псевдоэлементы.

blockquote, blockquote::before, blockquote::after {
  color: navy;

  & {
    border: 1px solid navy;
  }
}

Можно было бы ожидать, что и blockquote , и её псевдоэлементы будут иметь текст и границы navy цвета, но это не так. Поскольку селектор & не может представлять псевдоэлементы, вложенные стили границ будут применяться только к цитате.

При создании составных селекторов с использованием & и селекторов типа селектор типа должен идти первым, без пробелов между ними.

/* valid css nesting */
.feature {
  p& {
    font-weight: bold;
  }
}

/* invalid css nesting */
.feature {
  &p {
    font-weight: bold;
  }
}

Это правило позволяет использовать вложенность CSS совместно с инструментами предварительной обработки, такими как Sass. В Sass запись &p добавит родительский селектор к вложенному селектору типа, и результатом будет .featurep .

Вложенность at-правил

Правила условной группы CSS, такие как @container , @media , @supports и @layer также могут быть вложенными.

.feature {
  @media (min-width: 40em) {
    /* ... */
  }

  @container (inline-size > 900px) {
    /* ... */
  }
}

.feature {
  @supports (display: grid) {
    /* ... */
  }
}

.feature {
  @layer component {
    h2 {
      /* ... */
    }
  }
}

Проверьте свое понимание

Что представляет собой селектор & при использовании CSS Nesting?

Вложенный дочерний селектор
Неверно.
Родительский селектор
Правильный!
ближайший селектор братьев
Неверно.

Глубина вложения может составлять только два уровня.

Истинный
Неверно.
ЛОЖЬ
Правильный!

Какие at-правила могут быть вложенными?

@media
Правильный!
@container
Правильный!
@import
Неверно.
@supports
Правильный!
@layer
Правильный!