Una delle nostre funzionalità preferite del preprocessore CSS è ora integrata nel linguaggio: le regole di stile di annidamento.
Prima dell'annidamento, ogni selettore doveva essere dichiarato esplicitamente, separatamente l'uno dall'altro. Ciò comporta ripetizioni, un foglio di stile voluminoso e un'esperienza di creazione frammentata.
.nesting { color: hotpink; } .nesting > .is { color: rebeccapurple; } .nesting > .is > .awesome { color: deeppink; }
Dopo l'annidamento, i selettori possono essere continuati e le regole di stile correlate possono essere raggruppate al loro interno.
.nesting { color: hotpink; > .is { color: rebeccapurple; > .awesome { color: deeppink; } } }
Prova questa funzionalità nel browser.
L'annidamento aiuta gli sviluppatori riducendo la necessità di ripetere i selettori e di collocare le regole di stile per gli elementi correlati. Può anche aiutare gli stili a corrispondere all'HTML a cui sono destinati. Se il componente .nesting nell'esempio precedente è stato rimosso dal progetto, puoi eliminare l'intero gruppo anziché cercare i file per le istanze di selettori correlate.
L'annidamento può essere utile per: - Organizzazione - Riduzione delle dimensioni dei file - Refactoring
L'annidamento è disponibile a partire da Chrome 112 e può essere provato anche in Safari Technical Preview 162.
Inizia a utilizzare l'annidamento CSS
Per il resto di questo post,viene utilizzato il seguente sandbox demo per aiutarti a visualizzare le selezioni. In questo stato predefinito, non è selezionato nulla e tutto è visibile. Selezionando le varie forme e dimensioni, puoi esercitarti con la sintassi e vederla in azione.

All'interno del sandbox sono presenti cerchi, triangoli e quadrati. Alcuni sono piccoli, medi o grandi. Altri sono blu, rosa o viola. Sono tutti all'interno dell'elemento contenitore .demo. Di seguito è riportata un'anteprima degli elementi HTML a cui ti rivolgerai.
<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>
Esempi di annidamento
L'annidamento CSS ti consente di definire gli stili per un elemento nel contesto di un altro selettore.
.parent {
color: blue;
.child {
color: red;
}
}
In questo esempio, il .child selettore di classe è annidato all'interno
del .parent selettore di classe. Ciò significa che il selettore .child annidato verrà applicato solo agli elementi che sono figli di elementi con una classe .parent.
Questo esempio potrebbe essere scritto in alternativa utilizzando il simbolo &, per indicare esplicitamente dove deve essere inserita la classe padre.
.parent {
color: blue;
& .child {
color: red;
}
}
Questi due esempi sono funzionalmente equivalenti e il motivo per cui hai delle opzioni diventerà più chiaro man mano che esploreremo esempi più avanzati in questo articolo.
Selezionare i cerchi
Per questo primo esempio, l'attività consiste nell'aggiungere stili per sfumare e sfocare solo i cerchi all'interno della demo.
Senza annidamento, CSS oggi:
.demo .circle {
opacity: .25;
filter: blur(25px);
}
Con l'annidamento, esistono due modi validi:
/* & is explicitly placed in front of .circle */
.demo {
& .circle {
opacity: .25;
filter: blur(25px);
}
}
o
/* & + " " space is added for you */
.demo {
.circle {
opacity: .25;
filter: blur(25px);
}
}
Il risultato: tutti gli elementi all'interno di .demo con una classe .circle sono
sfocati e quasi invisibili:
Selezionare tutti i triangoli e i quadrati
Questa attività richiede la selezione di più elementi annidati, chiamati anche selettore di gruppo.
Senza annidamento, CSS oggi, esistono due modi:
.demo .triangle,
.demo .square {
opacity: .25;
filter: blur(25px);
}
oppure, utilizzando :is()
/* grouped with :is() */
.demo :is(.triangle, .square) {
opacity: .25;
filter: blur(25px);
}
Con l'annidamento, ecco due modi validi:
.demo {
& .triangle,
& .square {
opacity: .25;
filter: blur(25px);
}
}
o
.demo {
.triangle, .square {
opacity: .25;
filter: blur(25px);
}
}
Il risultato, all'interno di .demo rimangono solo gli elementi .circle:
Selezionare triangoli e cerchi di grandi dimensioni
Questa attività richiede un selettore composto, dove gli elementi devono avere entrambe le classi presenti per essere selezionati.
Senza annidamento, CSS oggi:
.demo .lg.triangle,
.demo .lg.square {
opacity: .25;
filter: blur(25px);
}
o
.demo .lg:is(.triangle, .circle) {
opacity: .25;
filter: blur(25px);
}
Con l'annidamento, ecco due modi validi:
.demo {
.lg.triangle,
.lg.circle {
opacity: .25;
filter: blur(25px);
}
}
o
.demo {
.lg {
&.triangle,
&.circle {
opacity: .25;
filter: blur(25px);
}
}
}
Il risultato: tutti i triangoli e i cerchi di grandi dimensioni sono nascosti all'interno di .demo:
Consiglio da pro con selettori composti e annidamento
Il simbolo & è utile in questo caso perché mostra esplicitamente come unire i selettori annidati. Considera l'esempio seguente:
.demo {
.lg {
.triangle,
.circle {
opacity: .25;
filter: blur(25px);
}
}
}
Sebbene sia un modo valido per l'annidamento, i risultati non corrisponderanno agli elementi che potresti aspettarti.
Il motivo è che senza & per specificare il risultato desiderato di .lg.triangle,
.lg.circle composto, il risultato effettivo sarebbe .lg .triangle, .lg
.circle; selettori discendenti.
Selezionare tutte le forme tranne quelle rosa
Questa attività richiede una pseudoclasse funzionale di negazione, in cui gli elementi non devono avere il selettore specificato.
Senza annidamento, CSS oggi:
.demo :not(.pink) {
opacity: .25;
filter: blur(25px);
}
Con l'annidamento, ecco due modi validi:
.demo {
:not(.pink) {
opacity: .25;
filter: blur(25px);
}
}
o
.demo {
& :not(.pink) {
opacity: .25;
filter: blur(25px);
}
}
Il risultato: tutte le forme non rosa sono nascoste all'interno di .demo:
Precisione e flessibilità con &
Supponiamo che tu voglia scegliere come target .demo con il selettore :not(). Per farlo, è necessario utilizzare &:
.demo {
&:not() {
...
}
}
In questo modo, .demo e :not() vengono combinati in .demo:not(), a differenza dell'esempio precedente
che richiedeva .demo :not(). Questo promemoria è molto importante quando si vuole annidare un'interazione :hover.
.demo {
&:hover {
/* .demo:hover */
}
:hover {
/* .demo :hover */
}
}
Altri esempi di annidamento
La specifica CSS per l'annidamento contiene molti altri esempi. Se vuoi saperne di più sulla sintassi tramite esempi, troverai una vasta gamma di esempi validi e non validi.
I prossimi esempi introdurranno brevemente una funzionalità di annidamento CSS per aiutarti a comprendere l'ampiezza delle funzionalità che introduce.
Annidamento @media
Può essere molto distraente spostarsi in un'altra area del foglio di stile per trovare le condizioni delle query multimediali che modificano un selettore e i relativi stili. Questa distrazione non esiste più grazie alla possibilità di annidare le condizioni direttamente all'interno del contesto.
Per comodità della sintassi, se la query multimediale annidata modifica solo gli stili per il contesto del selettore corrente, è possibile utilizzare una sintassi minima.
.card {
font-size: 1rem;
@media (width >= 1024px) {
font-size: 1.25rem;
}
}
È possibile utilizzare anche & in modo esplicito:
.card {
font-size: 1rem;
@media (width >= 1024px) {
&.large {
font-size: 1.25rem;
}
}
}
Questo esempio mostra la sintassi espansa con &, scegliendo come target anche le schede .large per dimostrare che le funzionalità di annidamento aggiuntive continuano a funzionare.
Scopri di più sull'annidamento delle @rules.
Annidamento ovunque
Tutti gli esempi fino a questo punto hanno continuato o aggiunto un contesto precedente. Se necessario, puoi modificare o riorganizzare completamente il contesto.
.card {
.featured & {
/* .featured .card */
}
}
Il simbolo & rappresenta un riferimento a un oggetto selettore (non a una stringa) e può essere inserito ovunque in un selettore annidato. Può essere inserito anche più volte:
.card {
.featured & & & {
/* .featured .card .card .card */
}
}
Sebbene questo esempio sembri un po' inutile, esistono sicuramente scenari in cui la possibilità di ripetere un contesto di selettore è utile.
Esempi di annidamento non validi
Esistono alcuni scenari di sintassi di annidamento non validi che potrebbero sorprenderti se hai utilizzato l'annidamento nei preprocessori.
Annidamento e concatenazione
Molte convenzioni di denominazione delle classi CSS si basano sulla possibilità di annidare per concatenare o aggiungere selettori come se fossero stringhe. Questo non funziona nell'annidamento CSS perché i selettori non sono stringhe, ma riferimenti a oggetti.
.card {
&--header {
/* is not equal to ".card--header" */
}
}
Nella specifica è disponibile una spiegazione più approfondita.
Esempio di annidamento complesso
Annidamento all'interno di elenchi di selettori e :is()
Considera il seguente blocco CSS di annidamento:
.one, #two {
.three {
/* some styles */
}
}
Questo è il primo esempio che inizia con un elenco di selettori e continua con l'annidamento. Gli esempi precedenti terminavano solo con un elenco di selettori. Non c'è nulla di non valido in questo esempio di annidamento, ma esiste un dettaglio di implementazione potenzialmente complesso sull'annidamento all'interno degli elenchi di selettori, in particolare quelli che includono un selettore ID.
Affinché l'intento dell'annidamento funzioni, qualsiasi elenco di selettori che non sia l'annidamento più interno verrà racchiuso tra :is() dal browser. Questo wrapping mantiene il raggruppamento dell'elenco di selettori all'interno di tutti i contesti creati. L'effetto collaterale di questo raggruppamento, :is(.one, #two), è che adotta la specificità del punteggio più alto all'interno dei selettori tra parentesi. Questo è il modo in cui :is() sempre funziona, ma potrebbe essere una sorpresa quando si utilizza la sintassi di annidamento perché non è esattamente ciò che è stato creato. In sintesi, l'annidamento con ID ed elenchi di selettori può portare a selettori con specificità molto elevata.
Per riepilogare chiaramente l'esempio complesso, il blocco di annidamento precedente verrà applicato al documento come segue:
:is(.one, #two) .three {
/* some styles */
}
Tieni d'occhio o insegna ai tuoi linter a avvisare quando l'annidamento all'interno di un elenco di selettori che utilizza un selettore ID, la specificità di tutto l'annidamento all'interno di quell'elenco di selettori sarà elevata.
Combinazione di annidamento e dichiarazioni
Considera il seguente blocco CSS di annidamento:
.card {
color: green;
& { color: blue; }
color: red;
}
Il colore degli elementi .card sarà blue.
Tutte le dichiarazioni di stile combinate vengono sollevate in alto, come se fossero state create prima di qualsiasi annidamento. Nella specifica sono disponibili ulteriori dettagli.
Esistono modi per aggirare il problema. Di seguito vengono racchiusi i tre stili di colore in &, che mantiene l'ordine a cascata come previsto dall'autore. Il colore degli elementi .card sarà rosso.
.card {
color: green;
& { color: blue; }
& { color: red; }
}
In realtà, è una buona pratica racchiudere tutti gli stili che seguono l'annidamento con un &.
.card {
color: green;
@media (prefers-color-scheme: dark) {
color: lightgreen;
}
& {
aspect-ratio: 4/3;
}
}
Rilevamento delle funzionalità
Esistono due ottimi modi per rilevare le funzionalità di annidamento CSS: utilizzare l'annidamento o utilizzare @supports per verificare la funzionalità di analisi dei selettori di annidamento.

Utilizzo dell'annidamento:
html {
.has-nesting {
display: block;
}
.no-nesting {
display: none;
}
}
Utilizzo di @supports:
@supports (selector(&)) {
/* nesting parsing available */
}
Il mio collega Bramus ha un ottimo Codepen che mostra questa strategia.
Debug con Chrome DevTools
Il supporto attuale per l'annidamento negli Strumenti per sviluppatori è minimo. Al momento, gli stili vengono rappresentati nel riquadro Stili come previsto, ma il tracciamento dell'annidamento e del relativo contesto di selettore completo non è ancora supportato. Abbiamo progettato e pianificato di rendere questa funzionalità trasparente e chiara.

Chrome 113 prevede un supporto aggiuntivo per l'annidamento CSS. Non perderti gli aggiornamenti.
Futuro =
L'annidamento CSS è solo alla versione 1. La versione 2 introdurrà una sintassi più semplice e potenzialmente meno regole da memorizzare. Esiste una forte richiesta che l'analisi dell'annidamento non sia limitata o presenti momenti difficili.
L'annidamento è un miglioramento significativo del linguaggio CSS. Ha implicazioni di creazione per quasi tutti gli aspetti architettonici di CSS. Questo impatto significativo deve essere esplorato e compreso a fondo prima che la versione 2 possa essere specificata in modo efficace.
Per concludere, ecco una demo
che utilizza @scope, l'annidamento e @layer tutti insieme. È tutto molto entusiasmante!
