Nidificazione dei CSS

Una delle nostre funzionalità di preprocessore CSS preferite è ora integrata nel linguaggio: le regole di stile di nidificazione.

Adam Argyle
Adam Argyle

Prima della nidificazione, ogni selettore doveva essere dichiarato esplicitamente, separatamente l'uno con l'altro. Questo porta a ripetizioni, in blocco di fogli di stile e a una un'esperienza senza intervento manuale.

Prima
.nesting {
  color: hotpink;
}

.nesting > .is {
  color: rebeccapurple;
}

.nesting > .is > .awesome {
  color: deeppink;
}

Dopo la nidificazione, i selettori possono essere le regole di stile continue e correlate possono essere raggruppate al suo interno.

Dopo
.nesting {
  color: hotpink;

  > .is {
    color: rebeccapurple;

    > .awesome {
      color: deeppink;
    }
  }
}

Fai questa prova nel browser.

La nidificazione aiuta gli sviluppatori a ridurre la necessità di ripetere i selettori e a regole di stile per la co-location per gli elementi correlati. Inoltre, consente di abbinare gli stili HTML che scelgono come target. Se il componente .nesting nell'esempio precedente era rimosso dal progetto, puoi eliminare l'intero gruppo anziché cercarlo per le istanze del selettore correlate.

Nesting può aiutarti con: - Organizzazione - Riduzione delle dimensioni del file - Refactoring

La nidificazione è disponibile da Chrome 112 e può anche essere provata in Safari Technical Preview 162.

Iniziare a utilizzare la nidificazione CSS

Nel resto di questo post,la seguente sandbox demo viene utilizzata per aiutarti e visualizzare le selezioni. In questo stato predefinito, non è selezionato nulla e tutto è visibile. Selezionando le varie forme e dimensioni, puoi esercitati con la sintassi e guardala in azione.

Una griglia colorata di cerchi piccoli e grandi, triangoli e quadrati.

All'interno del recinto della sabbia ci sono cerchi, triangoli e quadrati. Alcune sono piccole, medie o grande. Altre sono blu, rosa o viola. Si trovano tutti all'interno di .demo contenente l'elemento. Di seguito è riportata un'anteprima degli elementi HTML che ti verranno presentati targeting.

<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 nidificazione

La nidificazione CSS consente di definire gli stili di un elemento nel contesto di con un altro selettore.

.parent {
  color: blue;

  .child {
    color: red;
  }
}

In questo esempio, il selettore di classi .child è nidificato all'interno il selettore di classi .parent. Ciò significa che il selettore .child nidificato si applica solo agli elementi secondari di elementi con una classe .parent.

Questo esempio potrebbe essere scritto utilizzando il simbolo &, per indicare esplicitamente indicano dove deve essere posizionata la classe principale.

.parent {
  color: blue;

  & .child {
    color: red;
  }
}

Questi due esempi sono equivalenti dal punto di vista funzionale e il motivo per cui hai opzioni diventerà più chiara a mano a mano che gli esempi più avanzati vengono approfonditi in questo articolo.

Selezionare le cerchie

Per questo primo esempio, l'attività consiste nell'aggiungere stili di dissolvenza e sfocamento cerchi all'interno della demo.

Senza nidificazione, il CSS oggi:

.demo .circle {
  opacity: .25;
  filter: blur(25px);
}

Con la nidificazione, 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);
  }
}

Risultato: tutti gli elementi all'interno di .demo con una classe .circle vengono sfocato e quasi invisibile:

La griglia colorata di forme non contiene più cerchi,
    sono molto deboli sullo sfondo.
. Prova una demo

Selezione di triangoli e quadrati

Questa attività richiede la selezione di più elementi nidificati, chiamato anche selettore di gruppo.

Senza la nidificazione, oggi CSS esistono due modi:

.demo .triangle,
.demo .square {
  opacity: .25;
  filter: blur(25px);
}

o utilizzando :is()

/* grouped with :is() */
.demo :is(.triangle, .square) {
  opacity: .25;
  filter: blur(25px);
}

Con la nidificazione, ecco due modi validi:

.demo {
  & .triangle,
  & .square {
    opacity: .25;
    filter: blur(25px);
  }
}

o

.demo {
  .triangle, .square {
    opacity: .25;
    filter: blur(25px);
  }
}

Risultato, solo .circle elementi rimangono all'interno di .demo:

La griglia colorata di forme rimane con solo cerchi,
    tutte le altre forme sono quasi invisibili.
. Prova una demo

Selezionare triangoli e cerchi grandi

Questa attività richiede un selettore composto, in cui Per poter essere selezionati, gli elementi devono avere entrambe le classi.

Senza nidificazione, il 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 la nidificazione, ecco due modi validi:

.demo {
  .lg.triangle,
  .lg.circle {
    opacity: .25;
    filter: blur(25px);
  }
}

o

.demo {
  .lg {
    &.triangle,
    &.circle {
      opacity: .25;
      filter: blur(25px);
    }
  }
}

Risultato: tutti i triangoli e i cerchi grandi sono nascosti all'interno di .demo:

La griglia colorata ha solo forme piccole e medie visibili.
. Prova una demo
Suggerimento avanzato con selettori composti e nidificazione

Il simbolo & è il tuo amico qui in quanto mostra esplicitamente come aggiungere elementi selettori. Considera l'esempio seguente:

.demo {
  .lg {
    .triangle,
    .circle {
      opacity: .25;
      filter: blur(25px);
    }
  }
}

Sebbene sia un metodo valido per nidificare, i risultati non corrisponderanno agli elementi previsti. Il motivo è che senza & non specifichi il risultato desiderato della combinazione di .lg.triangle, .lg.circle, il risultato effettivo sarebbe .lg .triangle, .lg .circle; selettori discendenti.

Selezione di tutte le forme tranne quelle rosa

Questa attività richiede una pseudoclasse funzionale di negazione, in cui gli elementi non devono hanno il selettore specificato.

Senza nidificazione, il CSS oggi:

.demo :not(.pink) {
  opacity: .25;
  filter: blur(25px);
}

Con la nidificazione, ecco due modi validi:

.demo {
  :not(.pink) {
    opacity: .25;
    filter: blur(25px);
  }
}

o

.demo {
  & :not(.pink) {
    opacity: .25;
    filter: blur(25px);
  }
}

Risultato: tutte le forme non rosa sono nascoste all'interno di .demo:

La griglia colorata è ora monocromatica e mostra solo forme rosa.
. Prova una demo
Precisione e flessibilità con &

Supponiamo che tu voglia scegliere come target .demo con il selettore :not(). & è obbligatorio per che:

.demo {
  &:not() {
    ...
  }
}

In questo modo .demo e :not() vengono combinati in .demo:not(), a differenza della precedente esempio che richiedeva .demo :not(). Questo promemoria è molto importante quando vuoi nidificare un'interazione con :hover.

.demo {
  &:hover {
    /* .demo:hover */
  }

  :hover {
    /* .demo :hover */
  }
}

Altri esempi di nidificazione

La specifica CSS per la nidificazione è ricco di altri esempi. Se vuoi saperne di più sulla sintassi con gli esempi, copre un'ampia 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.

Nidificare i file @media

Può essere molto distraente passare a un'altra area del foglio di stile per trovare condizioni di query supporti che modificano un selettore e i suoi stili. Questa distrazione è scomparso dalla capacità di nidificare le condizioni direttamente all'interno del contesto.

Per comodità di sintassi, se la query multimediale nidificata sta modificando 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;
  }
}

Puoi usare esplicitamente & anche:

.card {
  font-size: 1rem;

  @media (width >= 1024px) {
    &.large {
      font-size: 1.25rem;
    }
  }
}

Questo esempio mostra la sintassi espansa con & e ha come target anche .large per dimostrare che le funzionalità di nidificazione aggiuntive continuano a funzionare.

Scopri di più sulla nidificazione di @rules.

Nidificare ovunque

Tutti gli esempi fino a questo punto sono stati continuati o aggiunti a un contesto precedente. Puoi modificare completamente o riorganizzare il contesto, se necessario.

.card {
  .featured & {
    /* .featured .card */
  }
}

Il simbolo & rappresenta un riferimento a un oggetto selettore (non una stringa) e può essere posizionato ovunque in un selettore nidificato. Può anche essere posizionato volte:

.card {
  .featured & & & {
    /* .featured .card .card .card */
  }
}

Sebbene questo esempio sia un po' inutile, ci sono sicuramente scenari in cui è utile poter ripetere il contesto di un selettore.

Esempi di nidificazione non validi

Alcuni scenari di sintassi di nidificazione non sono validi e potrebbero sorprenderti hai eseguito il nidificare i preprocessori.

Nesting e concatenazione

Molte convenzioni di denominazione delle classi CSS contano che la nidificazione sia in grado di concatenare o per aggiungere i selettori come se fossero stringhe. Questa operazione non funziona nella nidificazione CSS come i selettori non sono stringhe, ma riferimenti a oggetti.

.card {
  &--header {
    /* is not equal to ".card--header" */
  }
}

Puoi trovare una spiegazione più approfondita nelle specifiche.

Esempio di nidificazione ingannevole

Nidificare negli elenchi dei selettori e :is()

Considera il seguente blocco CSS di nidificazione:

.one, #two {
  .three {
    /* some styles */
  }
}

Questo è il primo esempio che inizia con un elenco di selettore e poi continua con la nidificazione. Gli esempi precedenti erano terminati solo con un elenco di selettore. Non c'è nulla di non valido in questo esempio di nidificazione, ma c'è un dettaglio di implementazione potenzialmente difficile sulla nidificazione all'interno degli elenchi di selezione, in particolare quelli che includono un selettore ID.

Affinché la nidificazione funzioni, qualsiasi elenco di selettore che non sia la nidificazione più interna verrà aggregato con :is() dal browser. Questo wrapping mantiene il raggruppamento dell'elenco di selettore all'interno di qualsiasi contesto di creazione. L'effetto collaterale di questo raggruppamento, :is(.one, #two), è che adotta la specificità del punteggio più alto all'interno dei selettori tra parentesi. :is() funziona sempre in questo modo, ma potrebbe sorprendere l'utilizzo della sintassi di nidificazione, perché non è esattamente ciò che è stato creato. Il trucco, riassunto: la nidificazione con ID ed elenchi di selettori può portare a selettori di specificità molto elevati.

Per riassumere chiaramente l'esempio complicato, il blocco di nidificazione precedente verrà applicato al documento come segue:

:is(.one, #two) .three {
  /* some styles */
}

Tieni d'occhio o insegna ai tuoi linter ad avvisarti quando esegui il nidificazione all'interno di un elenco di selettore che utilizza un selettore ID. La specificità di tutta la nidificazione all'interno dell'elenco di selettore sarà elevata.

Combinare nidificazione e dichiarazioni

Considera il seguente blocco CSS di nidificazione:

.card {
  color: green;
  & { color: blue; }
  color: red;
}

Il colore degli elementi .card sarà blue.

Le dichiarazioni di stile mescolate vengono sollevate verso l'alto, come se fossero creati prima della nidificazione. Puoi trovare ulteriori dettagli nelle specifiche.

Ci sono modi per evitarlo. Il seguente comando aggrega i tre stili di colore in &, mantiene l'ordine a cascata come previsto dall'autore. Il colore di Gli elementi .card verranno visualizzati in rosso.

.card {
  color: green;
  & { color: blue; }
  & { color: red; }
}

Anzi, è buona norma aggregare con un & tutti gli stili che seguono la nidificazione.

.card {
  color: green;

  @media (prefers-color-scheme: dark) {
    color: lightgreen;
  }

  & {
    aspect-ratio: 4/3;
  }
}

Rilevamento delle caratteristiche

Esistono due metodi molto efficaci per rilevare la funzionalità di nidificazione CSS: utilizzare la nidificazione o @supports per verificare la funzionalità di analisi del selettore di nidificazione.

Uno screenshot della demo di Codepen di Bramus, in cui viene chiesto se il browser supporta
  Nidificazione CSS. Sotto questa domanda è presente una casella verde che indica il supporto.

Utilizzo della nidificazione:

html {
  .has-nesting {
    display: block;
  }

  .no-nesting {
    display: none;
  }
}

Utilizzo di @supports:

@supports (selector(&)) {
  /* nesting parsing available */
}

Il mio collega Bramus ha un fantastico Codepen che mostra questa strategia.

Debug con Chrome DevTools

Il supporto attuale per la nidificazione in DevTools è minimo. Al momento troverai gli stili vengono rappresentati nel riquadro Stili come previsto, ma tracciando la nidificazione e il contesto completo del selettore non è ancora supportato. Abbiamo progettazione e progetti per rendere tutto trasparente e chiaro.

Uno screenshot della sintassi di nidificazione di Chrome DevTools.

Chrome 113 prevede di supportare ulteriore supporto per la nidificazione dei CSS. Non perderti gli aggiornamenti.

Il futuro

Nesting CSS è disponibile solo nella versione 1. La versione 2 introdurrà una maggiore quantità di zuccheri sintattici e potenzialmente meno regole per memorizzare. Per l'analisi della nidificazione esiste un'elevata richiesta o si trovano in momenti difficili.

La nidificazione rappresenta un grande miglioramento del linguaggio CSS. Ha implicazioni di creazione a quasi tutti gli aspetti architetturali dei CSS. Questo grande impatto deve essere profondamente esplorato e compreso prima che la versione 2 possa essere specificata in modo efficace.

Come ultimo pensiero, ecco una demo che utilizza @scope, nidificazione e @layer insieme. È tutto molto emozionante!

Una scheda leggera su uno sfondo grigio. La scheda ha titolo e testo,
  alcuni pulsanti di azione e un&#39;immagine in stile cyber punk.