Membantu memilih sintaksis untuk penyusunan bertingkat CSS

Dua sintaksis yang bersaing memerlukan bantuan Anda dalam menentukan sintaksis mana yang harus dipertahankan hingga menjadi kandidat spesifikasi.

Penyusunan CSS adalah penambahan sintaksis praktis yang memungkinkan CSS ditambahkan di dalam set aturan. Jika Anda pernah menggunakan SCSS, Less, atau Stylus, Anda pasti pernah melihat beberapa variasi ini:

.nesting {
  color: hotpink;

  > .is {
    color: rebeccapurple;

    > .awesome {
      color: deeppink;
    }
  }
}

Setelah dikompilasi menjadi CSS reguler oleh praprosesor, akan berubah menjadi CSS reguler seperti ini:

.nesting {
  color: hotpink;
}

.nesting > .is {
  color: rebeccapurple;
}

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

Versi CSS resmi dari sintaksis ini sedang dipertimbangkan secara serius dan kami memiliki perbedaan preferensi yang ingin kami selesaikan dengan bantuan komunitas. Bagian selanjutnya dari postingan ini akan memperkenalkan opsi sintaksis sehingga Anda dapat merasa yakin untuk mengikuti survei di akhir.

Mengapa contoh penyusunan bertingkat yang persis seperti di atas tidak dapat menjadi sintaksis untuk penyusunan bertingkat CSS?

Ada beberapa alasan mengapa sintaksis penyusunan yang paling populer tidak dapat digunakan apa adanya:

  1. Penguraian yang ambigu
    Beberapa pemilih bertingkat dapat terlihat persis seperti properti dan praprosesor dapat menyelesaikan dan mengelolanya pada waktu build. Mesin browser tidak akan memiliki kemampuan yang sama, sehingga pemilih tidak boleh diinterpretasikan secara longgar.

  2. Konflik parsing preprosesor
    Cara CSS untuk menyusun tidak boleh merusak preprosesor atau alur kerja penyusunan developer yang ada. Hal ini akan mengganggu dan tidak sopan bagi ekosistem dan komunitas tersebut.

  3. Menunggu :is()
    Penyusunan dasar tidak memerlukan :is(), tetapi penyusunan yang lebih kompleks memerlukan :is(). Lihat Contoh #3 untuk pengantar ringan tentang daftar dan penyusunan bertingkat selektor. Bayangkan jika daftar pemilih berada di tengah-tengah pemilih, bukan di awal. Dalam kasus tersebut, :is() diperlukan untuk mengelompokkan pemilih di tengah-tengah pemilih lain.

Ringkasan perbandingan

Kami ingin menerapkan nesting CSS dengan benar, dan untuk itu kami melibatkan komunitas. Bagian berikut akan membantu menjelaskan tiga kemungkinan versi yang kami evaluasi. Kemudian, kita akan membahas beberapa contoh penggunaan untuk perbandingan, dan di akhir akan ada survei singkat yang menanyakan mana yang lebih Anda sukai secara keseluruhan.

Opsi 1: @nest

Ini adalah sintaksis yang ditentukan saat ini dalam CSS Nesting 1. Cara ini menawarkan cara mudah untuk menyusun gaya penambahan dengan memulai pemilih bertingkat baru dengan &. API ini juga menawarkan @nest sebagai cara untuk menempatkan konteks & di mana saja di dalam pemilih baru, seperti saat Anda tidak hanya menambahkan subjek. API ini fleksibel dan minimal, tetapi Anda harus mengingat @nest atau &, bergantung pada kasus penggunaan Anda.

Opsi 2: @nest dibatasi

Ini adalah alternatif yang lebih ketat, dalam upaya untuk mengurangi biaya yang disebutkan dalam mengingat dua metode penyusunan. Sintaksis terbatas ini hanya memungkinkan terjadinya penyusunan setelah @nest, sehingga tidak ada pola praktis hanya untuk penambahan. Menghilangkan ambiguitas pilihan, membuat satu cara yang mudah diingat untuk menyusun, tetapi mengorbankan keringkasan demi konvensi.

Opsi 3: Kurung

Untuk menghindari sintaksis ganda atau kekacauan tambahan yang terkait dengan proposal @nest, Miriam Suzanne dan Elika Etemad mengusulkan sintaksis alternatif yang mengandalkan tanda kurung kurawal tambahan. Hal ini memberikan kejelasan sintaksis, dengan hanya dua karakter tambahan, dan tidak ada aturan @ baru. Hal ini juga memungkinkan aturan bertingkat dikelompokkan berdasarkan jenis nesting yang diperlukan, sebagai cara untuk menyederhanakan beberapa pemilih bertingkat yang serupa.

Contoh 1 - Penyeleksian langsung

@nest

.foo {
  color: #111;

  & .bar {
    color: #eee;
  }
}

@nest selalu

.foo {
  color: #111;

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

tanda kurung

.foo {
  color: #111;

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

CSS yang setara

.foo {
  color: #111;
}

.foo .bar {
  color: #eee;
}

Contoh 2 - Penyesuaian gabungan

@nest

.foo {
  color: blue;

  &.bar {
    color: red;
  }
}

@nest selalu

.foo {
  color: blue;

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

tanda kurung

.foo {
  color: blue;

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

CSS yang setara

.foo {
  color: blue;
}

.foo.bar {
  color: red;
}

Contoh 3 - Daftar pemilih dan penyusunan bertingkat

@nest

.foo, .bar {
  color: blue;

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

@nest selalu

.foo, .bar {
  color: blue;

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

tanda kurung

.foo, .bar {
  color: blue;

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

CSS yang setara

.foo, .bar {
  color: blue;
}

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

Contoh 4 - Beberapa level

@nest

figure {
  margin: 0;

  & > figcaption {
    background: lightgray;

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

@nest selalu

figure {
  margin: 0;

  @nest & > figcaption {
    background: lightgray;

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

tanda kurung

figure {
  margin: 0;

  {
    & > figcaption {
      background: lightgray;

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

CSS yang setara

figure {
  margin: 0;
}

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

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

Contoh 5 - Penautan induk atau perubahan subjek

@nest

.foo {
  color: red;

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

@nest selalu

.foo {
  color: red;

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

tanda kurung

.foo {
  color: red;

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

CSS yang setara

.foo {
  color: red;
}

.parent .foo {
  color: blue;
}

Contoh 6 - Mencampur penyusunan langsung dan induk

@nest

.foo {
  color: blue;

  @nest .bar & {
    color: red;

    &.baz {
      color: green;
    }
  }
}

@nest selalu

.foo {
  color: blue;

  @nest .bar & {
    color: red;

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

tanda kurung

.foo {
  color: blue;

  {
    .bar & {
      color: red;

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

CSS yang setara

.foo {
  color: blue;
}

.bar .foo {
  color: red;
}

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

Contoh 7 - Penyesuaian kueri media

@nest

.foo {
  display: grid;

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

atau secara eksplisit / diperpanjang

.foo {
  display: grid;

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

@nest selalu (selalu eksplisit)

.foo {
  display: grid;

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

tanda kurung

.foo {
  display: grid;

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

atau secara eksplisit / diperpanjang

.foo {
  display: grid;

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

CSS yang setara

.foo {
  display: grid;
}

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

Contoh 8 - Menggabungkan grup

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

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

tanda kurung

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 yang setara

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

Contoh 9 - Grup bertingkat kompleks "Kitchen Sink"

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

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

tanda kurung

dialog {
  border: none;

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

    & > form {
      display: grid;

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

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

CSS yang setara

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

Saatnya memberikan suara

Semoga Anda merasa bahwa perbandingan dan contoh sintaksis yang kami evaluasi ini adil. Tinjau dengan cermat dan beri tahu kami pilihan Anda di bawah. Kami menghargai bantuan Anda dalam memajukan penyusunan CSS ke sintaksis yang akan kita kenal dan sukai bersama.

Ikuti survei!