Hilfe beim Auswählen einer Syntax für die CSS-Verschachtelung

Zwei konkurrierende Syntaxen benötigen Ihre Hilfe bei der Bestimmung, welche zu einem Spezifikationskandidat befördert werden sollte.

Argyle
Adam Argyle
Miriam
Miriam Suzanne

Die CSS-Verschachtelung ist eine praktische Syntaxergänzung, mit der CSS innerhalb eines Regelsatzes hinzugefügt werden kann. Wenn Sie SCSS, Less oder Eingabestift verwendet haben, kennen Sie sicher schon einige Varianten davon:

.nesting {
  color: hotpink;

  > .is {
    color: rebeccapurple;

    > .awesome {
      color: deeppink;
    }
  }
}

Was, nachdem der Präprozessor in reguläres CSS kompiliert hat, zu regulärem CSS-Code umgewandelt wird, sieht so aus:

.nesting {
  color: hotpink;
}

.nesting > .is {
  color: rebeccapurple;
}

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

Eine offizielle CSS-Version dieser Syntax wird intensiv in Betracht gezogen und wir haben eine Spaltung, die wir bevorzugen, dass wir die Hilfe der Community nutzen möchten, um das Gleichgewicht zu lösen. Im weiteren Verlauf dieses Posts werden die Syntaxoptionen vorgestellt, damit Sie sich am Ende einer Umfrage informiert fühlen.

Warum kann das oben gezeigte Verschachtelungsbeispiel nicht genau die Syntax für die CSS-Verschachtelung sein?

Es gibt einige Gründe, warum die beliebteste Verschachtelungssyntax nicht unverändert verwendet werden kann:

  1. Mehrdeutiges Parsen
    Einige verschachtelte Selektoren können wie Attribute aussehen und Präprozessoren können sie beim Build-Prozess auflösen und verwalten. Browser-Engines haben nicht dieselben Angebote. Selectors dürfen nicht zu unübersichtlich interpretiert werden.

  2. Konflikte beim Parsen von Präprozessoren
    Durch die CSS-Verschachtelung sollten Präprozessoren oder vorhandene verschachtelte Workflows des Entwicklers nicht unterbrochen werden. Dies würde sich negativ auf diese Umgebungen und Communitys auswirken und wäre unberücksichtigt.

  3. Warten auf :is()
    Für die einfache Verschachtelung ist :is() nicht erforderlich, für eine komplexere Verschachtelung jedoch schon. In Beispiel 3 finden Sie eine kurze Einführung in Selektorlisten und die Verschachtelung. Angenommen, die Selektorliste befindet sich in der Mitte eines Selektors und nicht am Anfang. In diesen Fällen ist :is() erforderlich, um die Selektoren in der Mitte eines anderen Selektors zu gruppieren.

Was wir vergleichen

Wir möchten eine korrekte Verschachtelung von CSS erreichen und binden daher die Community ein. In den folgenden Abschnitten werden die drei möglichen Versionen beschrieben, die wir evaluieren. Anschließend sehen wir uns einige Anwendungsbeispiele zum Vergleich an. Am Ende werden Sie in einer kurzen Umfrage gefragt, was Sie insgesamt bevorzugen.

Option 1: @nest

Das ist die aktuell in CSS Verschachtelung 1 angegebene Syntax. Es bietet eine bequeme Möglichkeit, Stile zu verschachteln, indem neue verschachtelte Selektoren mit & gestartet werden. Außerdem bietet er @nest, um den &-Kontext an einer beliebigen Stelle innerhalb eines neuen Selektors zu platzieren, z. B. wenn Sie nicht nur Themen anfügen. Es ist flexibel und minimal, muss aber je nach Anwendungsfall @nest oder & merken.

Option 2: @nest eingeschränkt

Dies ist eine strengere Alternative, um den Aufwand für das Speichern von zwei Verschachtelungsmethoden zu reduzieren. Diese eingeschränkte Syntax lässt nur die Verschachtelung nach @nest zu. Es gibt also kein praktisches Muster, mit dem nur Anfügungen möglich sind. Ambiguität der Auswahl wird beseitigt, um eine leicht zu merkende Verschachtelungsmethode zu schaffen, aber die Genauigkeit zugunsten einer Konvention vernachlässigt.

Option 3: Klammern

Um die doppelte Syntax oder zusätzlichen Durcheinander bei den @nest-Vorschlägen zu vermeiden, schlagen Miriam Suzanne und Elika Etemad eine alternative Syntax vor, die stattdessen auf zusätzlichen geschweiften Klammern basiert. Dies sorgt für übersichtliche Syntax mit nur zwei zusätzlichen Zeichen und ohne neue @-Regeln. Außerdem können verschachtelte Regeln nach der erforderlichen Verschachtelungsart gruppiert werden, um mehrere ähnlich verschachtelte Selektoren zu vereinfachen.

Beispiel 1 – Direkte Verschachtelung

@Nest

.foo {
  color: #111;

  & .bar {
    color: #eee;
  }
}

Immer @nest

.foo {
  color: #111;

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

Klammern

.foo {
  color: #111;

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

Entsprechendes CSS

.foo {
  color: #111;
}

.foo .bar {
  color: #eee;
}

Beispiel 2 – Zusammengesetzte Verschachtelung

@Nest

.foo {
  color: blue;

  &.bar {
    color: red;
  }
}

Immer @nest

.foo {
  color: blue;

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

Klammern

.foo {
  color: blue;

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

Entsprechendes CSS

.foo {
  color: blue;
}

.foo.bar {
  color: red;
}

Beispiel 3 – Auswahllisten und Verschachtelung

@Nest

.foo, .bar {
  color: blue;

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

Immer @nest

.foo, .bar {
  color: blue;

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

Klammern

.foo, .bar {
  color: blue;

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

Entsprechendes CSS

.foo, .bar {
  color: blue;
}

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

Beispiel 4 – Mehrere Ebenen

@Nest

figure {
  margin: 0;

  & > figcaption {
    background: lightgray;

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

Immer @nest

figure {
  margin: 0;

  @nest & > figcaption {
    background: lightgray;

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

Klammern

figure {
  margin: 0;

  {
    & > figcaption {
      background: lightgray;

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

Entsprechendes CSS

figure {
  margin: 0;
}

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

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

Beispiel 5 – Verschachtelung übergeordneter Elemente oder Themenwechsel

@Nest

.foo {
  color: red;

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

Immer @nest

.foo {
  color: red;

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

Klammern

.foo {
  color: red;

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

Entsprechendes CSS

.foo {
  color: red;
}

.parent .foo {
  color: blue;
}

Beispiel 6 – Direkte und übergeordnete Verschachtelung kombinieren

@Nest

.foo {
  color: blue;

  @nest .bar & {
    color: red;

    &.baz {
      color: green;
    }
  }
}

Immer @nest

.foo {
  color: blue;

  @nest .bar & {
    color: red;

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

Klammern

.foo {
  color: blue;

  {
    .bar & {
      color: red;

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

Entsprechendes CSS

.foo {
  color: blue;
}

.bar .foo {
  color: red;
}

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

Beispiel 7 – Verschachtelung von Medienabfragen

@Nest

.foo {
  display: grid;

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

oder ausdrücklich / erweitert

.foo {
  display: grid;

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

@nest immer (ist immer explizit)

.foo {
  display: grid;

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

Klammern

.foo {
  display: grid;

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

oder ausdrücklich / erweitert

.foo {
  display: grid;

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

Entsprechendes CSS

.foo {
  display: grid;
}

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

Beispiel 8 – Gruppen verschachteln

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

Immer @nest

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

Klammern

fieldset {
  border-radius: 10px;

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

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

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

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

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

Beispiel 9: Komplexe Gruppe „Küchenspüle“

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

Immer @nest

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

Klammern

dialog {
  border: none;

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

    & > form {
      display: grid;

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

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

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

Zeit zum Abstimmen

Hoffentlich waren Sie der Meinung, dass dies ein fairer Vergleich der Syntaxoptionen war, die wir bewerten. Bitte lesen Sie sie sorgfältig durch und teilen Sie uns unten mit, welche Sie bevorzugen. Vielen Dank, dass Sie uns dabei helfen, die CSS-Verschachtelung zu einer Syntax zu entwickeln, die wir alle kennen und schätzen werden.

Nimm an der Umfrage teil!