Een van onze favoriete CSS-preprocessorfuncties is nu in de taal zelf ingebouwd: het nesten van stijlregels.
Vóór de introductie van geneste selectors moest elke selector afzonderlijk en expliciet worden gedeclareerd. Dit leidde tot herhaling, omvangrijke stylesheets en een onsamenhangende gebruikerservaring.
.nesting { color: hotpink; } .nesting > .is { color: rebeccapurple; } .nesting > .is > .awesome { color: deeppink; }
Na het nesten kunnen selectors worden voortgezet en kunnen de bijbehorende stijlregels erin worden gegroepeerd.
.nesting { color: hotpink; > .is { color: rebeccapurple; > .awesome { color: deeppink; } } }
Probeer dit eens in de browser .
Geneste elementen helpen ontwikkelaars door de noodzaak tot het herhalen van selectors te verminderen en tegelijkertijd stijlregels voor gerelateerde elementen bij elkaar te plaatsen. Het kan er ook voor zorgen dat stijlen beter aansluiten bij de HTML waarop ze gericht zijn. Als het .nesting component in het vorige voorbeeld uit het project zou worden verwijderd, zou je de hele groep kunnen verwijderen in plaats van in de bestanden te zoeken naar gerelateerde selector-instanties.
Geneste code kan helpen bij: - Organisatie - Het verkleinen van de bestandsgrootte - Refactoring
De mogelijkheid om elementen in een nest te plaatsen is beschikbaar vanaf Chrome 112 en kan ook worden uitgeprobeerd in Safari Technical Preview 162 .
Aan de slag met geneste CSS
In de rest van dit bericht wordt de volgende demo-sandbox gebruikt om u te helpen de selecties te visualiseren. In deze standaardtoestand is niets geselecteerd en is alles zichtbaar. Door de verschillende vormen en groottes te selecteren, kunt u de syntax oefenen en in actie zien.

In de sandbox bevinden zich cirkels, driehoeken en vierkanten. Sommige zijn klein, middelgroot of groot. Andere zijn blauw, roze of paars. Ze bevinden zich allemaal binnen het .demo -element. Hieronder ziet u een voorbeeld van de HTML-elementen waarop u zich gaat richten.
<div class="demo">
<div class="sm triangle pink"></div>
<div class="sm triangle blue"></div>
<div class="square blue"></div>
<div class="sm square pink"></div>
<div class="sm square blue"></div>
<div class="circle pink"></div>
…
</div>
Voorbeelden van geneste structuren
Met geneste CSS-stijlen kun je stijlen voor een element definiëren binnen de context van een andere selector.
.parent {
color: blue;
.child {
color: red;
}
}
In dit voorbeeld is de klasseselector .child genest binnen de klasseselector .parent . Dit betekent dat de geneste .child selector alleen van toepassing is op elementen die kinderen zijn van elementen met de klasse .parent .
Dit voorbeeld kan ook met het symbool & worden geschreven, om expliciet aan te geven waar de bovenliggende klasse moet worden geplaatst.
.parent {
color: blue;
& .child {
color: red;
}
}
Deze twee voorbeelden zijn functioneel equivalent en de reden waarom je opties hebt, zal duidelijker worden naarmate er in dit artikel meer geavanceerde voorbeelden worden besproken.
De cirkels selecteren
Voor dit eerste voorbeeld is het de bedoeling om stijlen toe te voegen waarmee alleen de cirkels in de demo vervagen en onscherp worden.
Zonder geneste CSS, vandaag de dag:
.demo .circle {
opacity: .25;
filter: blur(25px);
}
Bij geneste structuren zijn er twee geldige manieren:
/* & is explicitly placed in front of .circle */
.demo {
& .circle {
opacity: .25;
filter: blur(25px);
}
}
of
/* & + " " space is added for you */
.demo {
.circle {
opacity: .25;
filter: blur(25px);
}
}
Het resultaat is dat alle elementen binnen .demo met de klasse .circle wazig en bijna onzichtbaar zijn:

Driehoeken en vierkanten selecteren
Deze taak vereist het selecteren van meerdere geneste elementen, ook wel een groepsselector genoemd.
Zonder geneste CSS zijn er tegenwoordig twee manieren:
.demo .triangle,
.demo .square {
opacity: .25;
filter: blur(25px);
}
of, met behulp van :is()
/* grouped with :is() */
.demo :is(.triangle, .square) {
opacity: .25;
filter: blur(25px);
}
Bij geneste structuren zijn er twee geldige manieren:
.demo {
& .triangle,
& .square {
opacity: .25;
filter: blur(25px);
}
}
of
.demo {
.triangle, .square {
opacity: .25;
filter: blur(25px);
}
}
Het resultaat is dat alleen .circle elementen binnen .demo overblijven:

Het selecteren van grote driehoeken en cirkels
Deze taak vereist een samengestelde selector , waarbij elementen beide klassen moeten bezitten om geselecteerd te kunnen worden.
Zonder geneste CSS, vandaag de dag:
.demo .lg.triangle,
.demo .lg.square {
opacity: .25;
filter: blur(25px);
}
of
.demo .lg:is(.triangle, .circle) {
opacity: .25;
filter: blur(25px);
}
Bij geneste structuren zijn er twee geldige manieren:
.demo {
.lg.triangle,
.lg.circle {
opacity: .25;
filter: blur(25px);
}
}
of
.demo {
.lg {
&.triangle,
&.circle {
opacity: .25;
filter: blur(25px);
}
}
}
Het resultaat is dat alle grote driehoeken en cirkels verborgen zijn in .demo .

Professionele tip voor het gebruik van samengestelde selectoren en nesting.
Het & -symbool is hier erg handig, omdat het expliciet laat zien hoe je geneste selectors aan elkaar koppelt. Neem bijvoorbeeld het volgende:
.demo {
.lg {
.triangle,
.circle {
opacity: .25;
filter: blur(25px);
}
}
}
Hoewel dit een geldige manier is om te nesten, zullen de resultaten niet overeenkomen met de elementen die je wellicht verwacht. De reden hiervoor is dat zonder & om het gewenste resultaat van .lg.triangle, .lg.circle samengevoegd te specificeren, het werkelijke resultaat .lg .triangle, .lg .circle zou zijn; afstammingsselectoren .
Alle vormen selecteren, behalve de roze.
Voor deze taak is een negatiefunctionele pseudoklasse vereist, waarbij elementen niet de opgegeven selector mogen hebben.
Zonder geneste CSS, vandaag de dag:
.demo :not(.pink) {
opacity: .25;
filter: blur(25px);
}
Bij geneste structuren zijn er twee geldige manieren:
.demo {
:not(.pink) {
opacity: .25;
filter: blur(25px);
}
}
of
.demo {
& :not(.pink) {
opacity: .25;
filter: blur(25px);
}
}
Het resultaat is dat alle vormen die niet roze zijn, verborgen zijn in de map .demo :

Precisie en flexibiliteit met &
Stel dat je .demo wilt selecteren met de selector :not() . Daarvoor is & vereist :
.demo {
&:not() {
...
}
}
Dit combineert .demo en :not() tot .demo:not() , in tegenstelling tot het vorige voorbeeld waar .demo :not() nodig was. Deze herinnering is erg belangrijk wanneer je een :hover interactie wilt nesten.
.demo {
&:hover {
/* .demo:hover */
}
:hover {
/* .demo :hover */
}
}
Meer voorbeelden van geneste structuren
De CSS-specificatie voor geneste elementen bevat talloze voorbeelden. Als je de syntax beter wilt leren kennen aan de hand van voorbeelden, biedt deze een breed scala aan geldige en ongeldige voorbeelden.
De volgende voorbeelden zullen kort een CSS-nestingfunctie introduceren, zodat u de vele mogelijkheden ervan beter begrijpt.
Nesting @media
Het kan erg afleidend zijn om naar een ander gedeelte van het stylesheet te gaan om mediaquery-voorwaarden te vinden die een selector en de bijbehorende stijlen wijzigen. Die afleiding is verdwenen doordat je de voorwaarden direct in de context kunt nesten.
Voor het gemak van de syntaxis kan, als de geneste mediaquery alleen de stijlen voor de huidige selectorcontext wijzigt, een minimale syntaxis worden gebruikt.
.card {
font-size: 1rem;
@media (width >= 1024px) {
font-size: 1.25rem;
}
}
Het gebruik van & kan ook expliciet worden toegepast:
.card {
font-size: 1rem;
@media (width >= 1024px) {
&.large {
font-size: 1.25rem;
}
}
}
Dit voorbeeld laat de uitgebreide syntaxis met & zien, en richt zich tevens op .large -kaarten om aan te tonen dat extra geneste functionaliteiten blijven werken.
Leer meer over het nesten van @rules .
Overal nestelen
Alle voorbeelden tot nu toe zijn voortgebouwd op of aangevuld met een eerdere context. U kunt de context indien nodig volledig wijzigen of herschikken.
.card {
.featured & {
/* .featured .card */
}
}
Het & -symbool verwijst naar een selectorobject (niet naar een tekenreeks) en kan overal in een geneste selector worden geplaatst. Het kan zelfs meerdere keren worden gebruikt:
.card {
.featured & & & {
/* .featured .card .card .card */
}
}
Hoewel dit voorbeeld er wat nutteloos uitziet, zijn er zeker scenario's waarin het handig is om een selectorcontext te kunnen herhalen.
Ongeldige geneste voorbeelden
Er zijn een paar ongeldige scenario's voor geneste structuren die je wellicht zullen verrassen als je gewend bent om geneste structuren in preprocessors te gebruiken.
Geneste structuur en samenvoeging
Veel CSS-naamgevingsconventies gaan ervan uit dat geneste selectors kunnen worden samengevoegd of toegevoegd alsof het strings zijn. Dit werkt echter niet in geneste CSS, omdat selectors geen strings zijn, maar objectreferenties.
.card {
&--header {
/* is not equal to ".card--header" */
}
}
Een meer gedetailleerde uitleg is te vinden in de specificaties .
Lastig voorbeeld van geneste structuren
Geneste functies binnen selectorlijsten en :is()
Overweeg het volgende geneste CSS-blok:
.one, #two {
.three {
/* some styles */
}
}
Dit is het eerste voorbeeld dat begint met een selectorlijst en vervolgens verder genest wordt. Eerdere voorbeelden eindigden altijd met een selectorlijst. Er is niets ongeldigs aan dit geneste voorbeeld, maar er is een potentieel lastig implementatiedetail met betrekking tot het nesten binnen selectorlijsten, met name die lijsten die een ID-selector bevatten.
Om de bedoeling van de geneste structuur te laten werken, wordt elke selectorlijst die niet de binnenste geneste is, door de browser omwikkeld met :is() . Deze omwikkeling zorgt ervoor dat de selectorlijst binnen de door de auteur gedefinieerde contexten blijft gegroepeerd. Het neveneffect van deze groepering, :is(.one, #two) , is dat de specificiteit van de selector met de hoogste score binnen de haakjes wordt overgenomen. Zo werkt :is() altijd, maar het kan een verrassing zijn bij het gebruik van geneste syntax, omdat het niet precies overeenkomt met wat de auteur voor ogen had. De truc samengevat: geneste structuren met ID's en selectorlijsten kunnen leiden tot selectors met een zeer hoge specificiteit.
Om het lastige voorbeeld nog eens duidelijk samen te vatten, wordt het voorgaande geneste blok als volgt op het document toegepast:
:is(.one, #two) .three {
/* some styles */
}
Houd er rekening mee, of leer je linters om te waarschuwen, wanneer je elementen nestelt binnen een selectorlijst die een ID-selector gebruikt. De specificiteit van alle geneste elementen binnen die selectorlijst zal namelijk hoog zijn.
Het combineren van geneste structuren en declaraties
Overweeg het volgende geneste CSS-blok:
.card {
color: green;
& { color: blue; }
color: red;
}
De kleur van .card -elementen zal blue zijn.
Alle declaraties met een gemengde stijl worden naar boven verplaatst, alsof ze zijn geschreven voordat er sprake was van geneste structuren. Meer details zijn te vinden in de specificatie .
Er zijn manieren om dit te omzeilen. Het volgende plaatst de drie kleurstijlen in & , waardoor de cascadevolgorde behouden blijft zoals de auteur wellicht bedoeld heeft. De kleur van .card elementen zal rood zijn.
.card {
color: green;
& { color: blue; }
& { color: red; }
}
Het is zelfs goede gewoonte om alle stijlen die na een geneste structuur volgen, tussen een & te plaatsen.
.card {
color: green;
@media (prefers-color-scheme: dark) {
color: lightgreen;
}
& {
aspect-ratio: 4/3;
}
}
Kenmerkdetectie
Er zijn twee uitstekende manieren om geneste CSS te detecteren: gebruik de nesting-eigenschap of gebruik @supports om te controleren of geneste selectors correct geparseerd kunnen worden.

Geneste structuren gebruiken:
html {
.has-nesting {
display: block;
}
.no-nesting {
display: none;
}
}
Gebruikmakend van @supports :
@supports (selector(&)) {
/* nesting parsing available */
}
Mijn collega Bramus heeft een fantastische Codepen waarin deze strategie wordt gedemonstreerd.
Foutopsporing uitvoeren met Chrome DevTools
De huidige ondersteuning voor geneste stijlen in DevTools is minimaal. Stijlen worden momenteel wel correct weergegeven in het deelvenster Stijlen, maar het traceren van de geneste stijlen en de volledige selectorcontext wordt nog niet ondersteund. We hebben plannen om dit transparant en duidelijk te maken.

Chrome versie 113 zal naar verwachting extra ondersteuning bieden voor geneste CSS-structuren. Blijf op de hoogte.
De toekomst
CSS-nesting bevindt zich nog in versie 1. Versie 2 introduceert meer syntactische suiker en mogelijk minder regels om te onthouden. Er is veel vraag naar een parsing-functionaliteit die niet beperkt is en geen lastige momenten kent.
Geneste structuren vormen een grote verbetering voor de CSS-taal. Ze hebben gevolgen voor vrijwel elk architectonisch aspect van CSS. Deze grote impact moet grondig worden onderzocht en begrepen voordat versie 2 effectief kan worden gespecificeerd.
Tot slot, hier is een demo die @scope , nesting en @layer combineert. Het is allemaal erg spannend!
