Guida alla scelta di una sintassi per la nidificazione CSS

Abbiamo bisogno del tuo aiuto per determinare quale delle due sintassi in competizione deve essere scelta come possibile specifica.

Adam Argyle
Adam Argyle
Miriam Suzanne
Miriam Suzanne

Il nidificazione CSS è un'aggiunta alla sintassi che consente di aggiungere CSS all'interno di un insieme di regole. Se hai utilizzato SCSS, Less o Stylus, hai sicuramente visto alcune varianti di questo:

.nesting {
  color: hotpink;

  > .is {
    color: rebeccapurple;

    > .awesome {
      color: deeppink;
    }
  }
}

Che, dopo essere stato compilato in CSS normale dal preprocessore, diventa CSS normale come questo:

.nesting {
  color: hotpink;
}

.nesting > .is {
  color: rebeccapurple;
}

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

Stiamo valutando seriamente una versione CSS ufficiale di questa sintassi e abbiamo riscontrato una divisione nelle preferenze. Vorremmo chiedere l'aiuto della community per risolvere il problema. Nel resto di questo post verranno presentate le opzioni di sintassi, in modo che al termine tu possa rispondere a un sondaggio.

Perché l'esempio esatto di nidificazione mostrato sopra non può essere la sintassi per la nidificazione CSS?

Esistono alcuni motivi per cui la sintassi di nidificazione più utilizzata non può essere utilizzata così com'è:

  1. Analisi ambigua
    Alcuni selettori nidificati possono assomigliare esattamente a proprietà e pre-processori sono in grado di risolverli e gestirli in fase di compilazione. I motori dei browser non avranno le stesse funzionalità, i selettori non devono mai essere interpretati in modo approssimativo.

  2. Conflitti di analisi del preprocessore
    Il modo in cui CSS gestisce l'organizzazione gerarchica non deve interrompere i preprocessori o i flussi di lavoro di nesting degli sviluppatori esistenti. Ciò sarebbe dannoso e sconsiderato per questi ecosistemi e queste community.

  3. In attesa di :is()
    L'organizzazione in nidificazioni di base non richiede :is(), ma è necessaria per le nidificazioni più complesse. Consulta l'esempio 3 per un'introduzione breve agli elenchi di selettori e al nidificazione. Immagina che l'elenco di selettori si trovi al centro di un selettore instead of all'inizio, in questi casi è necessario :is() per agrupare i selettori al centro di un altro selettore.

Panoramica degli elementi a confronto

Vogliamo fare in modo che l'organizzazione CSS sia corretta e, in questo spirito, stiamo coinvolgendo la community. Le sezioni seguenti descrivono le tre possibili versioni che stiamo valutando. Esamineremo poi alcuni esempi di utilizzo per il confronto e alla fine ti presenteremo un breve sondaggio in cui ti chiederemo quale preferisci in generale.

Opzione 1: @nest

Questa è la sintassi attualmente specificata in CSS Nesting 1. Offre un modo pratico per nidificare gli stili di accodamento iniziando nuovi selettori nidificati con &. Offre inoltre @nest come un modo per inserire il contesto & in qualsiasi punto di un nuovo selettore, ad esempio quando non aggiungi solo soggetti. È flessibile e minimale, ma richiede di ricordare @nest o & a seconda del caso d'uso.

Opzione 2: @nest restricted

Si tratta di un'alternativa più rigida, nel tentativo di ridurre la spesa menzionata per ricordare due metodi di nidificazione. Questa sintassi limitata consente il nidificazione solo dopo @nest, quindi non esiste un pattern di comodità solo per l'aggiunta. Rimuovere l'ambiguità di scelta, creando un modo facile da ricordare per nidificare, ma sacrificando la concisione a favore della convenzione.

Opzione 3: parentesi

Per evitare la doppia sintassi o la confusione aggiuntiva associata alle proposte @nest, Miriam Suzanne ed Elika Etemad hanno proposto una sintassi alternativa che si basa invece su parentesi graffe aggiuntive. Ciò offre una maggiore chiarezza sintattica, con solo due caratteri aggiuntivi e nessuna nuova regola at. Consente inoltre di raggruppare le regole nidificate in base al tipo di nidificazione richiesto, in modo da semplificare più selettori nidificati in modo simile.

Esempio 1: nidificazione diretta

@nest

.foo {
  color: #111;

  & .bar {
    color: #eee;
  }
}

@nest always

.foo {
  color: #111;

  @nest & .bar {
    color: #eee;
  }
}

parentesi

.foo {
  color: #111;

  {
    & .bar {
      color: #eee;
    }
  }
}

CSS equivalente

.foo {
  color: #111;
}

.foo .bar {
  color: #eee;
}

Esempio 2: nidificazione composta

@nest

.foo {
  color: blue;

  &.bar {
    color: red;
  }
}

@nest always

.foo {
  color: blue;

  @nest &.bar {
    color: red;
  }
}

parentesi

.foo {
  color: blue;

  {
    &.bar {
      color: red;
    }
  }
}

CSS equivalente

.foo {
  color: blue;
}

.foo.bar {
  color: red;
}

Esempio 3: elenchi di selettori e nidificazione

@nest

.foo, .bar {
  color: blue;

  & + .baz,
  &.qux {
    color: red;
  }
}

@nest always

.foo, .bar {
  color: blue;

  @nest & + .baz,
  &.qux {
    color: red;
  }
}

parentesi

.foo, .bar {
  color: blue;

  {
    & + .baz,
    &.qux {
      color: red;
    }
  }
}

CSS equivalente

.foo, .bar {
  color: blue;
}

:is(.foo, .bar) + .baz,
:is(.foo, .bar).qux {
  color: red;
}

Esempio 4: più livelli

@nest

figure {
  margin: 0;

  & > figcaption {
    background: lightgray;

    & > p {
      font-size: .9rem;
    }
  }
}

@nest always

figure {
  margin: 0;

  @nest & > figcaption {
    background: lightgray;

    @nest & > p {
      font-size: .9rem;
    }
  }
}

parentesi

figure {
  margin: 0;

  {
    & > figcaption {
      background: lightgray;

      {
        & > p {
          font-size: .9rem;
        }
      }
    }
  }
}

CSS equivalente

figure {
  margin: 0;
}

figure > figcaption {
  background: hsl(0 0% 0% / 50%);
}

figure > figcaption > p {
  font-size: .9rem;
}

Esempio 5: nidificazione del gruppo principale o modifica dell'oggetto

@nest

.foo {
  color: red;

  @nest .parent & {
    color: blue;
  }
}

@nest always

.foo {
  color: red;

  @nest .parent & {
    color: blue;
  }
}

parentesi

.foo {
  color: red;

  {
    .parent & {
      color: blue;
    }
  }
}

CSS equivalente

.foo {
  color: red;
}

.parent .foo {
  color: blue;
}

Esempio 6: combinazione di nidificazione diretta e nidificazione principale

@nest

.foo {
  color: blue;

  @nest .bar & {
    color: red;

    &.baz {
      color: green;
    }
  }
}

@nest always

.foo {
  color: blue;

  @nest .bar & {
    color: red;

    @nest &.baz {
      color: green;
    }
  }
}

parentesi

.foo {
  color: blue;

  {
    .bar & {
      color: red;

      {
        &.baz {
          color: green;
        }
      }
    }
  }
}

CSS equivalente

.foo {
  color: blue;
}

.bar .foo {
  color: red;
}

.bar .foo.baz {
  color: green;
}

Esempio 7: nidificazione di query sui media

@nest

.foo {
  display: grid;

  @media (width => 30em) {
    grid-auto-flow: column;
  }
}

o esplicitamente / estesa

.foo {
  display: grid;

  @media (width => 30em) {
    & {
      grid-auto-flow: column;
    }
  }
}

@nest always (è sempre esplicito)

.foo {
  display: grid;

  @media (width => 30em) {
    @nest & {
      grid-auto-flow: column;
    }
  }
}

parentesi

.foo {
  display: grid;

  @media (width => 30em) {
    grid-auto-flow: column;
  }
}

o esplicitamente / estesa

.foo {
  display: grid;

  @media (width => 30em) {
    & {
      grid-auto-flow: column;
    }
  }
}

CSS equivalente

.foo {
  display: grid;
}

@media (width => 30em) {
  .foo {
    grid-auto-flow: column;
  }
}

Esempio 8: gruppi nidificati

@nest

fieldset {
  border-radius: 10px;

  &:focus-within {
    border-color: hotpink;
  }

  & > legend {
    font-size: .9em;
  }

  & > div {
    & + div {
      margin-block-start: 2ch;
    }

    & > label {
      line-height: 1.5;
    }
  }
}

@nest always

fieldset {
  border-radius: 10px;

  @nest &:focus-within {
    border-color: hotpink;
  }

  @nest & > legend {
    font-size: .9em;
  }

  @nest & > div {
    @nest & + div {
      margin-block-start: 2ch;
    }

    @nest & > label {
      line-height: 1.5;
    }
  }
}

parentesi

fieldset {
  border-radius: 10px;

  {
    &:focus-within {
      border-color: hotpink;
    }
  }

  > {
    legend {
      font-size: .9em;
    }

    div {
      + div {
        margin-block-start: 2ch;
      }

      > label {
        line-height: 1.5;
      }
    }}
  }
}

CSS equivalente

fieldset {
  border-radius: 10px;
}

fieldset:focus-within {
  border-color: hotpink;
}

fieldset > legend {
  font-size: .9em;
}

fieldset > div + div {
  margin-block-start: 2ch;
}

fieldset > div > label {
  line-height: 1.5;
}

Esempio 9: gruppo nidificato complesso "Lavello da cucina"

@nest

dialog {
  border: none;

  &::backdrop {
    backdrop-filter: blur(25px);
  }

  & > form {
    display: grid;

    & > :is(header, footer) {
      align-items: flex-start;
    }
  }

  @nest html:has(&[open]) {
    overflow: hidden;
  }
}

@nest always

dialog {
  border: none;

  @nest &::backdrop {
    backdrop-filter: blur(25px);
  }

  @nest & > form {
    display: grid;

    @nest & > :is(header, footer) {
      align-items: flex-start;
    }
  }

  @nest html:has(&[open]) {
    overflow: hidden;
  }
}

parentesi

dialog {
  border: none;

  {
    &::backdrop {
      backdrop-filter: blur(25px);
    }

    & > form {
      display: grid;

      {
        & > :is(header, footer) {
          align-items: flex-start;
        }
      }
    }
  }

  {
    html:has(&[open]) {
      overflow: hidden;
    }
  }
}

CSS equivalente

dialog {
  border: none;
}

dialog::backdrop {
  backdrop-filter: blur(25px);
}

dialog > form {
  display: grid;
}

dialog > form > :is(header, footer) {
  align-items: flex-start;
}

html:has(dialog[open]) {
  overflow: hidden;
}

È ora di votare

Ci auguriamo che questo confronto sia stato equo e che ti abbia fornito un esempio delle opzioni di sintassi che stiamo valutando. Esaminale attentamente e indicaci la tua preferenza di seguito. Ti ringraziamo per averci aiutato a migliorare il nesting CSS con una sintassi che tutti impareremo a conoscere e apprezzare.

Rispondi al sondaggio.