Umieszczanie

Zagnieżdżanie reguł stylów CSS może sprawić, że arkusze stylów będą bardziej uporządkowane, czytelne i łatwiejsze w utrzymaniu.

Przegląd

Skoro wiesz już, czym są selektory, pewnie zastanawiasz się, jak lepiej je uporządkować w arkuszach stylów. Załóżmy, że stosujesz style do elementów w sekcji „Funkcje” w swojej witrynie. Dzięki zagnieżdżaniu możesz zgrupować te style w regule .feature w ten sposób:

.feature {
  button {
    color: blue;
  }

  .link {
    color: red;
  }

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

To tak, jakby każdy styl był zapisywany osobno:

.feature button {
  color: blue;
}

.feature .link {
   color: red;
}

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

Zagnieżdżanie może mieć dowolną liczbę poziomów.

.feature {
  .heading {
    color: blue;

    a {
      color: green;
    }
  }
}

Grupowanie i tworzenie relacji

Zagnieżdżanie umożliwia bardziej zwięzłe grupowanie reguł stylów i ustalanie między nimi relacji.

Domyślnie zagnieżdżona reguła będzie powiązana z regułą zewnętrzną za pomocą kombinatora potomka. Aby zmienić relacje, użyj selektorów w zagnieżdżonych regułach.

/* 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;
  }
}

Definiowanie relacji bezpośrednich za pomocą selektora &

Możesz też użyć selektora &, aby bardziej precyzyjnie określić zagnieżdżanie reguł stylu. Symbol & reprezentuje selektor elementu nadrzędnego.

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

Odpowiadałoby to zapisaniu stylów w ten sposób:

.feature button {
  color: blue;
}

Kiedy wymagane jest &

Bez symbolu & zagnieżdżone selektory będą selektorami potomków selektora nadrzędnego. Aby utworzyć selektory złożone, & jest wymagany.

.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 */
  }
}

Możesz też zmienić kontekst i umieścić selektor & na końcu selektora podrzędnego lub po obu jego stronach.


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

W ostatnim przykładzie dodajemy style do obrazów w elemencie z klasą .my-component. Może to być przydatne, jeśli pracujesz nad projektem, w którym nie możesz dodać elementu class ani id.

Zagnieżdżanie i specyficzność

Podobnie jak :is(), selektor zagnieżdżania przyjmuje szczegółowość selektora o najwyższej szczegółowości na liście selektorów elementu nadrzędnego.

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

.intro a {
  color: blue;
}

Pierwsza reguła kieruje reklamy na wszystkie linki w elementach #main-header.intro, nadając im zielony kolor.

Druga reguła próbuje to zastąpić, aby linki w elemencie .intro były niebieskie.

Jeśli przyjrzymy się szczegółowości każdej reguły, zobaczymy, dlaczego to nie działa.

/* 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;
}

Ponieważ pierwsza reguła ma w swojej liście selektorów symbol id, a reguły zagnieżdżone przyjmują specyficzność selektora o najwyższej specyficzności, ma ona wyższą specyficzność niż druga reguła. Linki są zielone nawet w przypadku elementów a, które nie znajdują się w elemencie z selektorem #main-header.

Nieprawidłowe zagnieżdżenie

Podobnie jak w przypadku selektora :is(), selektor zagnieżdżania nie może reprezentować pseudoelementów.

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

  & {
    border: 1px solid navy;
  }
}

Można by oczekiwać, że element blockquote i jego pseudoelementy będą miały tekst i obramowania w kolorze navy, ale tak nie jest. Selektor & nie może reprezentować pseudoelementów, więc zagnieżdżone style obramowania będą stosowane tylko do elementu blockquote.

Podczas tworzenia selektorów złożonych za pomocą selektorów & i typu selektor typu musi być pierwszy i nie może być między nimi spacji.

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

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

Ta reguła umożliwia zagnieżdżanie CSS w połączeniu z narzędziami do wstępnego przetwarzania, takimi jak Sass. W Sass zapisanie &p spowoduje dołączenie selektora nadrzędnego do zagnieżdżonego selektora typu, a wynikiem będzie .featurep.

Zagnieżdżanie reguł @

Reguły grup warunkowych CSS, takie jak @container, @media, @supports i @layer, mogą być też zagnieżdżone.

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

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

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

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

Sprawdź swoją wiedzę

Co oznacza selektor & w przypadku zagnieżdżania CSS?

Zagnieżdżony selektor podrzędny
Źle.
Selektor elementu nadrzędnego
Dobrze!
selektor najbliższego elementu równorzędnego,
Źle.

Możesz zagnieżdżać tylko na 2 poziomach.

Prawda
Źle.
Fałsz
Dobrze!

Które reguły @ można zagnieżdżać?

@media
Dobrze!
@container
Dobrze!
@import
Źle.
@supports
Dobrze!
@layer
Dobrze!