Membantu memilih sintaksis untuk penyusunan bertingkat CSS

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

Adam Argyle
Adam Argyle
Miriam Suzanne
Miriam Suzanne

Penyusunan bertingkat CSS adalah penambahan sintaksis praktis yang memungkinkan CSS ditambahkan di dalam set aturan. Jika pernah menggunakan SCSS, Less, atau Stylus, Anda pastinya telah melihat beberapa ragamnya:

.nesting {
  color: hotpink;

  > .is {
    color: rebeccapurple;

    > .awesome {
      color: deeppink;
    }
  }
}

Yang setelah dikompilasi menjadi CSS reguler oleh preprocessor, 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 dengan serius dan kami memiliki perbedaan preferensi yang ingin kami gunakan untuk meminta bantuan komunitas untuk memecahkan kebuntuan. Bagian selanjutnya dari postingan ini akan memperkenalkan opsi sintaksis sehingga Anda dapat merasa terinformasi untuk mengikuti survei di bagian akhir.

Mengapa contoh penyusunan bertingkat yang tepat yang ditampilkan di atas tidak dapat menjadi sintaksis untuk penyusunan bertingkat CSS?

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

  1. Pemrosesan ambigu
    Beberapa pemilih bertingkat dapat terlihat persis seperti properti dan preprocessor yang dapat me-resolve dan mengelolanya pada waktu build. Mesin browser tidak akan memiliki affordance yang sama, pemilih tidak boleh ditafsirkan secara longgar.

  2. Konflik penguraian preprocessor
    Cara CSS untuk membuat bertingkat tidak boleh merusak preprocessor atau alur kerja bertingkat developer yang ada. Hal ini akan mengganggu dan tidak mempertimbangkan ekosistem dan komunitas tersebut.

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

Ringkasan hal yang kita bandingkan

Kami ingin membuat CSS nesting dengan benar, dan dengan semangat itu, kami menyertakan komunitas. Bagian berikut akan membantu menjelaskan tiga kemungkinan versi yang kami evaluasi. Kemudian, kita akan membahas beberapa contoh penggunaan untuk perbandingan, dan di bagian akhir akan ada survei ringan yang menanyakan pilihan Anda secara keseluruhan.

Opsi 1: @nest

Ini adalah sintaksis yang ditentukan saat ini di CSS Nesting 1. Ini menawarkan cara yang mudah untuk menyusun gaya tambahan dengan memulai pemilih bertingkat baru dengan &. Fungsi ini juga menawarkan @nest sebagai cara untuk menempatkan konteks & di mana saja di dalam pemilih baru, seperti saat Anda tidak hanya menambahkan subjek. Ini fleksibel dan minimal, tetapi memerlukan Anda untuk 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 untuk mengingat dua metode penyusunan bertingkat. Sintaksis terbatas ini hanya memungkinkan penyusunan bertingkat terjadi setelah @nest, sehingga tidak ada pola praktis hanya tambahan. Menghapus ambiguitas pilihan, membuat satu cara yang mudah diingat untuk menyusun bertingkat, tetapi mengorbankan kejelasan demi konvensi.

Opsi 3: Tanda 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, hanya dengan dua karakter tambahan, dan tidak ada aturan at baru. Hal ini juga memungkinkan aturan bertingkat dikelompokkan menurut jenis tingkatan yang diperlukan, sebagai cara untuk menyederhanakan beberapa pemilih bertingkat yang serupa.

Contoh 1 - Penyusunan bertingkat langsung

@nest

.foo {
  color: #111;

  & .bar {
    color: #eee;
  }
}

@nest always

.foo {
  color: #111;

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

tanda kurung

.foo {
  color: #111;

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

CSS Setara

.foo {
  color: #111;
}

.foo .bar {
  color: #eee;
}

Contoh 2 - Penyusunan bertingkat gabungan

@nest

.foo {
  color: blue;

  &.bar {
    color: red;
  }
}

@nest always

.foo {
  color: blue;

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

tanda kurung

.foo {
  color: blue;

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

CSS Setara

.foo {
  color: blue;
}

.foo.bar {
  color: red;
}

Contoh 3 - Daftar pemilih dan tingkatan

@nest

.foo, .bar {
  color: blue;

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

@nest always

.foo, .bar {
  color: blue;

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

tanda kurung

.foo, .bar {
  color: blue;

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

CSS Setara

.foo, .bar {
  color: blue;
}

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

Contoh 4 - Beberapa tingkat

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

tanda kurung

figure {
  margin: 0;

  {
    & > figcaption {
      background: lightgray;

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

CSS Setara

figure {
  margin: 0;
}

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

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

Contoh 5 - Perubahan subjek atau tingkat induk

@nest

.foo {
  color: red;

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

@nest always

.foo {
  color: red;

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

tanda kurung

.foo {
  color: red;

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

CSS Setara

.foo {
  color: red;
}

.parent .foo {
  color: blue;
}

Contoh 6 - Menggabungkan tingkatan langsung dan induk

@nest

.foo {
  color: blue;

  @nest .bar & {
    color: red;

    &.baz {
      color: green;
    }
  }
}

@nest always

.foo {
  color: blue;

  @nest .bar & {
    color: red;

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

tanda kurung

.foo {
  color: blue;

  {
    .bar & {
      color: red;

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

CSS Setara

.foo {
  color: blue;
}

.bar .foo {
  color: red;
}

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

Contoh 7 - Penyusunan bertingkat kueri media

@nest

.foo {
  display: grid;

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

atau secara eksplisit / diperluas

.foo {
  display: grid;

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

@nest always (selalu vulgar)

.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 / diperluas

.foo {
  display: grid;

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

CSS Setara

.foo {
  display: grid;
}

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

Contoh 8 - Grup bertingkat

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

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

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

Waktunya memberikan suara

Semoga Anda merasa bahwa perbandingan tersebut adil dan merupakan contoh sampel dari opsi sintaksis yang kami evaluasi. Harap tinjau dengan cermat dan beri tahu kami mana yang Anda pilih di bawah. Kami berterima kasih atas bantuan Anda dalam meningkatkan tingkatan CSS ke sintaksis yang akan kita kenal dan sukai.

Ikuti survei ini.