Lapisan bertingkat akan tersedia di browser Anda

Lapisan bertingkat (aturan CSS @layer) akan hadir di Chromium 99, Firefox 97, dan Safari 15.4 Beta. Hal ini memungkinkan kontrol yang lebih eksplisit atas file CSS Anda untuk mencegah konflik kekhususan gaya. Hal ini sangat berguna untuk codebase besar, sistem desain, dan saat mengelola gaya pihak ketiga dalam aplikasi.

Pelapisan CSS dengan cara yang jelas akan mencegah penggantian gaya yang tidak terduga dan mendukung arsitektur CSS yang lebih baik.

Kekhususan CSS dan menurun

Kekhususan CSS adalah cara CSS menentukan gaya yang akan diterapkan pada elemen. Berbagai pemilih yang dapat Anda gunakan menentukan kekhususan aturan gaya apa pun. Misalnya, elemen tidak terlalu spesifik dibandingkan class atau atribut, sehingga kurang spesifik dibandingkan ID. Ini adalah bagian penting dalam mempelajari CSS.

Orang-orang beralih ke konvensi penamaan CSS seperti BEM untuk mencegah kekhususan penggantian secara tidak sengaja. Dengan memberikan hanya satu classname, semua elemen akan ditempatkan di bidang kekhususan yang sama. Namun, tidak selalu mungkin untuk mempertahankan gaya yang terorganisir seperti itu, terutama saat bekerja dengan kode dan sistem desain pihak ketiga.

Visual BEM kartu dengan class
Contoh ilustrasi penamaan BEM dari keepuptodate.com.

Lapisan bertingkat bertujuan untuk memecahkan masalah ini. Mereka memperkenalkan lapisan baru ke air terjun CSS. Dengan gaya berlapis, prioritas lapisan selalu mengalahkan kekhususan selektor.

Misalnya, pemilih .post a.link memiliki kekhususan lebih tinggi daripada .card a. Jika mencoba menyesuaikan gaya link, di dalam kartu, dalam postingan Anda akan menemukan bahwa pemilih yang lebih spesifik akan diterapkan.

Dengan menggunakan @layer, Anda dapat lebih spesifik tentang kekhususan gaya masing-masing, dan memastikan gaya link kartu Anda menggantikan gaya link postingan, meskipun kekhususannya mungkin lebih rendah secara numerik jika semua CSS Anda berada di bidang yang sama. Hal ini disebabkan adanya prioritas {i>cascade<i}. Gaya berlapis menciptakan "bidang" bertingkat baru.

Ilustrasi dari demo project tentang pengelompokan UI

Cara kerja @layer

Demo yang menampilkan warna link dengan impor
Lihat demo di Codepen.

Contoh ini menampilkan kecanggihan lapisan menurun, menggunakan @layer. Ada beberapa link yang ditampilkan: beberapa tanpa nama class tambahan yang diterapkan, satu dengan class .link, dan satu dengan class .pink. Selanjutnya, CSS menambahkan tiga lapisan: base, typography, dan utilities sebagai berikut:

@layer base {
  a {
    font-weight: 800;
    color: red; /* ignored */
  }

  .link {
    color: blue; /* ignored */
  }
}

@layer typography {
  a {
    color: green; /* styles *all* links */
  }
}

@layer utilities {
  .pink {
    color: hotpink;  /* styles *all* .pink's */
  }
}

Pada akhirnya, semua tautan berwarna hijau atau merah muda. Hal ini karena: meskipun .link memiliki kekhususan tingkat pemilih yang lebih tinggi daripada a, ada gaya warna pada a dengan prioritas yang lebih tinggi @layer. a { color: green } mengganti .link { color: blue } saat aturan hijau berada dalam lapisan setelah aturan biru.

Prioritas lapisan akan mengalahkan kekhususan elemen.

Mengatur lapisan

Anda dapat mengatur lapisan langsung di laman, seperti yang ditunjukkan di atas, atau Anda dapat mengaturnya di bagian atas file.

Urutan lapisan ditetapkan saat pertama kali nama lapisan muncul dalam kode Anda.

Artinya, jika Anda menambahkan kode berikut ke bagian atas file, semua link akan berwarna merah, dan link dengan class .link akan terlihat biru:

@layer utilities, typography, base;

Hal ini karena urutan lapisan sekarang dibalik, menempatkan utilitas terlebih dahulu dan di dasar terakhir. Oleh karena itu, aturan gaya di lapisan base akan selalu memiliki kekhususan yang lebih tinggi daripada aturan gaya di lapisan tipografi. Link tersebut tidak akan lagi berwarna hijau, tetapi akan berubah menjadi merah atau biru.

Screenshot Project Codepen
Lihat demo di Codepen.

Mengatur impor

Cara lain untuk menggunakan @layer adalah dengan mengimpor file. Anda dapat melakukannya secara langsung saat mengimpor gaya menggunakan fungsi layer() seperti dalam contoh berikut:

/* Base */
@import '../styles/base/normalize.css' layer(base); /* normalize or rest file */
@import '../styles/base/base.css' layer(base); /* body and base styles */
@import '../styles/base/theme.css' layer(theme); /* theme variables */
@import '../styles/base/typography.css' layer(theme); /* theme typography */
@import '../styles/base/utilities.css' layer(utilities); /* base utilities */

/* Layouts */
@import '../styles/components/post.css' layer(layouts); /* post layout */

/* Components */
@import '../styles/components/cards.css' layer(components); /* imports card */
@import '../styles/components/footer.css' layer(components); /* footer component */

Cuplikan kode di atas memiliki tiga lapisan: base,layouts, dan components. File normalisasi, tema, dan tipografi di base, dengan file post dalam layouts, serta cards dan footer keduanya di components. Saat mengimpor file, lapisan dibuat menggunakan fungsi lapisan. Pendekatan alternatifnya adalah mengatur lapisan Anda di bagian atas file, mendeklarasikannya sebelum impor apa pun:

@layer base,
       theme,
       layouts,
       components,
       utilities;

Sekarang, urutan @import gaya Anda tidak akan penting bagi urutan lapisan, karena sudah ditetapkan saat pertama kali nama lapisan. Anda tidak perlu mengkhawatirkan apa pun. Anda tetap dapat menetapkan file yang diimpor ke lapisan tertentu, tetapi urutan sudah ditetapkan.

Screenshot dari Project Codepen
Jelajahi project di Codepen.

Lapisan dan air terjun

Mari kita mundur selangkah dan melihat di mana {i>layer<i} digunakan dalam kaitannya dengan aliran yang lebih luas:

Ilustrasi Cascade

Urutan prioritasnya adalah sebagai berikut:

  • Agen Pengguna normal (prioritas terendah)
  • Pengguna Lokal @layer
  • Pengguna Lokal normal
  • Penulis @layers
  • Penulis normal
  • Penulis !important
  • Penulis @layer !important
  • Pengguna Lokal !important
  • !important** Agen Pengguna (prioritas tertinggi)

Anda dapat memperhatikan di sini bahwa gaya @layer !important dibalik. Gaya tersebut memiliki prioritas lebih tinggi, alih-alih kurang spesifik daripada gaya tidak berlapis (normal). Hal ini disebabkan oleh cara kerja !important dalam menurun: pengurangan normal dalam stylesheet dan membalikkan kekhususan tingkat lapisan normal (prioritas).

Lapisan bertingkat

Lapisan juga dapat disarangkan di dalam lapisan lain. Contoh berikut berasal dari penjelasan Lapisan Cascade dari Miriam Suzanne:

@layer default {
  p { max-width: 70ch; }
}

@layer framework {
  @layer default {
    p { margin-block: 0.75em; }
  }

  p { margin-bottom: 1em; }
}

Dalam cuplikan kode di atas, Anda dapat mengakses framework.default, menggunakan . sebagai penanda lapisan default yang disusun bertingkat dalam framework. Anda juga dapat menulisnya dalam format yang lebih singkat:

@layer framework.default {
  p { margin-block: 0.75em }
}

Lapisan dan urutan lapisan yang dihasilkan adalah:

  • default
  • framework.default
  • framework tidak berlapis
  • tidak berlapis

Hal yang perlu diperhatikan

Lapisan bertingkat sangat bagus jika Anda menggunakannya dengan benar, tetapi lapisan ini juga dapat menambah kebingungan dan hasil yang tidak terduga. Perhatikan hal-hal berikut saat bekerja dengan lapisan menurun:

Aturan 1: Jangan gunakan @layer untuk pencakupan

Lapisan bertingkat tidak memecahkan cakupan. Jika Anda memiliki file CSS dengan @layer, misalnya card.css dan ingin menata gaya semua link dalam kartu, jangan tulis gaya seperti:

a {
  …
}

Tindakan ini akan menyebabkan semua tag a dalam file Anda mendapatkan penggantian ini. Penting untuk memberi cakupan pada gaya Anda dengan benar:

.card a {
  …
}

Aturan 2: lapisan menurun diurutkan di belakang CSS yang tidak berlapis

Perlu diperhatikan bahwa file CSS berlapis tidak akan menggantikan CSS yang tidak berlapis. Ini adalah keputusan yang disengaja untuk mempermudah pengenalan lapisan dengan cara yang lebih masuk akal dalam menggunakan codebase yang ada. Menggunakan file reset.css, misalnya, merupakan titik awal yang baik dan kasus penggunaan untuk lapisan menurun.

Aturan 3: !important membalikkan kekhususan menurun

Meskipun gaya berlapis tidak terlalu spesifik dibandingkan gaya tidak berlapis secara umum, penggunaan !important akan membalikkan hal ini. Dalam lapisan, deklarasi dengan aturan !important lebih spesifik daripada gaya yang tidak berlapis.

Dalam hal ini, gaya !important akan membalikkan kekhususannya. Diagram di atas menunjukkan hal ini sebagai referensi: penulis @layers memiliki prioritas lebih rendah dibandingkan penulis biasa yang memiliki prioritas lebih rendah daripada penulis !important yang memiliki prioritas lebih rendah daripada penulis @layer !important.

Jika Anda memiliki beberapa lapisan, lapisan pertama dengan !important akan lebih diprioritaskan dari !important dan menjadi gaya yang paling spesifik.

Aturan 4: Memahami titik injeksi

Karena urutan lapisan ditentukan saat pertama kali muncul setiap nama lapisan dalam kode Anda, jika Anda menempatkan deklarasi @layer setelah mengimpor dan menyetel layer(), atau setelah pernyataan @layer yang berbeda, deklarasi tersebut dapat diabaikan. Tidak seperti di CSS, ketika aturan gaya yang paling jauh di bawah halaman diterapkan untuk lapisan bertingkat, urutannya ditetapkan pada instance pertama.

Ini dapat dalam daftar, dalam blok lapisan, atau impor. Jika Anda menempatkan @layer setelah daftar impor dengan layer(), tindakan tersebut tidak akan melakukan apa pun. Menempatkannya di bagian atas file akan membuat IA mengatur urutan {i>layer<i}, dan membantu Anda melihat lapisan di dalam arsitektur dengan jelas.

Aturan #5: Perhatikan kekhususan Anda

Dengan lapisan bertingkat, pemilih yang kurang spesifik (seperti a) akan mengganti pemilih yang lebih spesifik (seperti .link) jika pemilih yang kurang spesifik tersebut berada di lapisan yang lebih spesifik. Pertimbangkan hal berikut:

a di layer(components) akan menggantikan .pink di layer(utilities) jika: @layer utilities, components ditentukan. Meskipun merupakan bagian dari API yang disengaja, hal ini dapat membingungkan dan menyulitkan jika Anda tidak mengharapkannya.

Jadi jika Anda menulis class utilitas, selalu sertakan class tersebut sebagai lapisan dengan urutan yang lebih tinggi daripada komponen yang ingin Anda ganti. Anda mungkin berpikir “Saya baru saja menambahkan class .pink ini untuk mengubah warna dan tidak diterapkan”.

Pelajari lapisan menurun lebih lanjut

Anda juga dapat melihat referensi berikut untuk mempelajari lapisan menurun lebih lanjut: