Help bij het kiezen van een syntaxis voor CSS-nesten

Twee concurrerende syntaxis hebben uw hulp nodig bij het bepalen welke syntaxis moet worden bevorderd tot een specificatiekandidaat.

Adam Argyle
Adam Argyle
Mirjam Suzanne
Miriam Suzanne

CSS-nesten is een gemakkelijke syntaxistoevoeging waarmee CSS binnen een regelset kan worden toegevoegd. Als je SCSS , Less of Stylus hebt gebruikt, dan heb je zeker een paar smaken hiervan gezien:

.nesting {
  color: hotpink;

  > .is {
    color: rebeccapurple;

    > .awesome {
      color: deeppink;
    }
  }
}

Wat, nadat het door de preprocessor naar reguliere CSS is gecompileerd, als volgt in reguliere CSS verandert:

.nesting {
  color: hotpink;
}

.nesting > .is {
  color: rebeccapurple;
}

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

Er wordt sterk nagedacht over een officiële CSS-versie van deze syntaxis en we hebben de voorkeur dat we de hulp van de gemeenschap willen inschakelen om de knoop door te hakken. In de rest van dit bericht worden de syntaxisopties geïntroduceerd, zodat u zich aan het einde geïnformeerd voelt om een ​​enquête in te vullen.

Waarom kan het exacte nestvoorbeeld hierboven niet de syntaxis zijn voor CSS-nesten?

Er zijn een paar redenen waarom de populairste nest-syntaxis niet zoals deze kan worden gebruikt:

  1. Dubbelzinnige parsering
    Sommige geneste selectors kunnen er precies zo uitzien als eigenschappen en preprocessors kunnen deze tijdens het bouwen oplossen en beheren. Browsermotoren zullen niet dezelfde mogelijkheden hebben, selectors mogen nooit losjes worden geïnterpreteerd.

  2. Conflicten bij het parseren van de preprocessor
    De CSS-manier van nesten mag preprocessors of bestaande nestworkflows voor ontwikkelaars niet verbreken . Dit zou ontwrichtend en onattent zijn voor die ecosystemen en gemeenschappen.

  3. Wachten op :is()
    Voor basisnesten is :is() niet nodig, maar voor complexer nesten wel. Zie Voorbeeld #3 voor een korte introductie tot selectorlijsten en nesten. Stel je voor dat de selectorlijst zich in het midden van een selector bevindt in plaats van aan het begin, in die gevallen :is() vereist om de selectors in het midden van een andere selector te groeperen.

Overzicht van wat we vergelijken

We willen CSS-nesten goed krijgen, en in die geest betrekken we de gemeenschap erbij. In de volgende secties worden de drie mogelijke versies beschreven die we evalueren. Vervolgens bespreken we enkele gebruiksvoorbeelden ter vergelijking, en aan het einde zal er een korte enquête zijn waarin u wordt gevraagd welke uw voorkeur heeft.

Optie 1: @nest

Dit is de huidige gespecificeerde syntaxis in CSS Nesting 1 . Het biedt een handige manier om toevoegstijlen te nesten door nieuwe geneste selectors te starten met & . Het biedt ook @nest als een manier om de & -context overal in een nieuwe selector te plaatsen, bijvoorbeeld wanneer u niet alleen maar onderwerpen toevoegt. Het is flexibel en minimaal, maar gaat ten koste van het onthouden @nest of & , afhankelijk van je gebruiksscenario.

Optie 2: @nest beperkt

Dit is een strenger alternatief, in een poging de genoemde kosten voor het onthouden van twee nestmethoden te verminderen. Deze beperkte syntaxis staat alleen toe dat nesten plaatsvindt na @nest , dus er is geen gemakspatroon dat alleen wordt toegevoegd. Het wegnemen van de dubbelzinnigheid van de keuze, het creëren van een gemakkelijk te onthouden manier om te nestelen, maar het offert bondigheid op ten gunste van conventie.

Optie 3: Beugels

Om de dubbele syntaxis of extra rommel die gepaard gaat met de @nest voorstellen te vermijden, stelden Miriam Suzanne en Elika Etemad een alternatieve syntaxis voor die in plaats daarvan afhankelijk is van extra accolades. Dit zorgt voor duidelijkheid in de syntaxis, met slechts twee extra tekens en geen nieuwe at-regels. Het maakt het ook mogelijk om geneste regels te groeperen op basis van het vereiste type nesting, als een manier om meerdere op dezelfde manier geneste selectors te vereenvoudigen.

Voorbeeld 1 - Direct nesten

@nest

.foo {
  color: #111;

  & .bar {
    color: #eee;
  }
}

@nest altijd

.foo {
  color: #111;

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

beugels

.foo {
  color: #111;

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

Equivalente CSS

.foo {
  color: #111;
}

.foo .bar {
  color: #eee;
}

Voorbeeld 2 - Samengesteld nesten

@nest

.foo {
  color: blue;

  &.bar {
    color: red;
  }
}

@nest altijd

.foo {
  color: blue;

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

beugels

.foo {
  color: blue;

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

Equivalente CSS

.foo {
  color: blue;
}

.foo.bar {
  color: red;
}

Voorbeeld 3 - Selectielijsten en nesten

@nest

.foo, .bar {
  color: blue;

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

@nest altijd

.foo, .bar {
  color: blue;

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

beugels

.foo, .bar {
  color: blue;

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

Equivalente CSS

.foo, .bar {
  color: blue;
}

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

Voorbeeld 4 - Meerdere niveaus

@nest

figure {
  margin: 0;

  & > figcaption {
    background: lightgray;

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

@nest altijd

figure {
  margin: 0;

  @nest & > figcaption {
    background: lightgray;

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

beugels

figure {
  margin: 0;

  {
    & > figcaption {
      background: lightgray;

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

Equivalente CSS

figure {
  margin: 0;
}

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

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

Voorbeeld 5 - Ouder nesten of onderwerp veranderen

@nest

.foo {
  color: red;

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

@nest altijd

.foo {
  color: red;

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

beugels

.foo {
  color: red;

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

Equivalente CSS

.foo {
  color: red;
}

.parent .foo {
  color: blue;
}

Voorbeeld 6 - Direct nesten en oudernesten mengen

@nest

.foo {
  color: blue;

  @nest .bar & {
    color: red;

    &.baz {
      color: green;
    }
  }
}

@nest altijd

.foo {
  color: blue;

  @nest .bar & {
    color: red;

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

beugels

.foo {
  color: blue;

  {
    .bar & {
      color: red;

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

Equivalente CSS

.foo {
  color: blue;
}

.bar .foo {
  color: red;
}

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

Voorbeeld 7 - Nesten van mediaquery's

@nest

.foo {
  display: grid;

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

of expliciet/uitgebreid

.foo {
  display: grid;

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

@nest altijd (is altijd expliciet)

.foo {
  display: grid;

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

beugels

.foo {
  display: grid;

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

of expliciet/uitgebreid

.foo {
  display: grid;

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

Equivalente CSS

.foo {
  display: grid;
}

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

Voorbeeld 8 - Groepen nesten

@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 altijd

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

beugels

fieldset {
  border-radius: 10px;

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

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

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

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

Equivalente CSS

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

Voorbeeld 9 - Complexe nestgroep "Aanrecht"

@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 altijd

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

beugels

dialog {
  border: none;

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

    & > form {
      display: grid;

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

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

Equivalente CSS

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

Tijd om te stemmen

Hopelijk vind je dat dit een eerlijke vergelijking en voorbeeldschotel was van de syntaxisopties die we evalueren. Bekijk ze zorgvuldig en laat ons hieronder weten welke uw voorkeur heeft. We stellen het op prijs dat u ons helpt CSS-nesten te bevorderen tot een syntaxis die we allemaal zullen leren kennen en waarderen!

De enquete invullen!