Lapisan bertingkat akan tersedia di browser Anda

Lapisan kaskade (aturan CSS @layer) akan hadir di Chromium 99, Firefox 97, dan Safari 15.4 Beta. Alat ini memungkinkan kontrol yang lebih eksplisit terhadap 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.

Menambahkan lapisan CSS dengan cara yang jelas akan mencegah penggantian gaya yang tidak terduga dan mendorong arsitektur CSS yang lebih baik.

Spesifisitas CSS dan kaskade

Kekhususan CSS adalah cara CSS menentukan gaya yang akan diterapkan ke elemen mana. Berbagai pemilih yang dapat Anda gunakan menentukan kekhususan aturan gaya apa pun. Misalnya, elemen kurang spesifik daripada class atau atribut, yang pada gilirannya kurang spesifik daripada ID. Ini adalah bagian dasar dari mempelajari CSS.

Orang-orang beralih ke konvensi penamaan CSS seperti BEM untuk mencegah penggantian kekhususan secara tidak sengaja. Dengan memberikan satu nama class ke semuanya, semuanya akan ditempatkan pada bidang spesifitas yang sama. Namun, mempertahankan gaya yang teratur seperti itu tidak selalu memungkinkan, terutama saat menggunakan kode dan sistem desain pihak ketiga.

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

Lapisan cascade bertujuan untuk mengatasi masalah ini. Keduanya memperkenalkan lapisan baru ke cascade CSS. Dengan gaya berlapis, prioritas lapisan selalu mengalahkan kekhususan pemilih.

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

Dengan menggunakan @layer, Anda dapat lebih eksplisit tentang kekhususan gaya masing-masing, dan memastikan gaya link kartu Anda mengganti gaya link postingan, meskipun secara numerik kekhususannya mungkin lebih rendah jika semua CSS Anda berada di bidang yang sama. Hal ini karena prioritas cascade. Gaya berlapis membuat "bidang" kaskade baru.

Ilustrasi dari demo project untuk memisahkan UI

@layer sedang beraksi

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

Contoh ini menunjukkan kemampuan lapisan cascade, menggunakan @layer. Ada beberapa link yang ditampilkan: beberapa tanpa nama class tambahan yang diterapkan, satu dengan class .link, dan satu dengan class .pink. CSS kemudian 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 link berwarna hijau atau merah muda. Hal ini karena: meskipun .link memiliki kekhususan tingkat pemilih yang lebih tinggi daripada a, ada gaya warna pada a dalam @layer prioritas yang lebih tinggi. a { color: green } mengganti .link { color: blue } saat aturan hijau berada di lapisan setelah aturan biru.

Prioritas lapisan mengalahkan kekhususan elemen.

Mengatur lapisan

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

Urutan lapisan ditetapkan saat pertama kali setiap 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 berwarna biru:

@layer utilities, typography, base;

Hal ini karena urutan lapisan sekarang dibalik, menempatkan utilitas terlebih dahulu dan 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 lagi berwarna hijau, tetapi merah atau biru.

Screenshot Project Codepen
Lihat demo di Codepen.

Mengatur impor

Cara lain untuk menggunakan @layer adalah dengan file impor. 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 di layouts, serta cards dan footer di components. Saat file diimpor, lapisan dibuat instance-nya menggunakan fungsi lapisan. Pendekatan alternatifnya adalah mengatur lapisan di bagian atas file, mendeklarasikannya sebelum impor apa pun:

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

Sekarang, urutan @import gaya Anda tidak akan memengaruhi urutan lapisan, karena sudah ditetapkan pada instance pertama nama lapisan. Jadi, Anda tidak perlu khawatir lagi. Anda tetap dapat menetapkan file yang diimpor ke lapisan tertentu, tetapi pengurutannya sudah ditetapkan.

Screenshot dari Project Codepen
Jelajahi project di Codepen.

Lapisan dan kaskade

Mari kita mundur sejenak dan melihat tempat lapisan digunakan sehubungan dengan kaskade yang lebih luas:

Ilustrasi Cascade

Urutan prioritasnya adalah sebagai berikut:

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

Anda mungkin melihat di sini bahwa gaya @layer !important terbalik. Gaya berlapis memiliki prioritas yang lebih tinggi, bukan kurang spesifik daripada gaya non-berlapis (normal). Hal ini karena cara kerja !important dalam cascade: !important akan merusak cascade normal dalam stylesheet Anda dan membalikkan kekhususan tingkat lapisan normal (prioritas).

Lapisan bertingkat

Lapisan juga dapat disusun bertingkat 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 kaskade dapat sangat berguna jika Anda menggunakannya dengan benar, tetapi juga dapat menyebabkan kebingungan tambahan dan hasil yang tidak terduga. Perhatikan hal-hal berikut saat menggunakan lapisan cascade:

Aturan 1: Jangan gunakan @layer untuk cakupan

Lapisan cascade tidak menyelesaikan 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. Anda tetap harus menentukan cakupan gaya dengan benar:

.card a {
  
}

Aturan 2: lapisan cascade diurutkan di belakang CSS tanpa lapisan

Perlu diperhatikan bahwa file CSS berlapis tidak akan mengganti CSS tanpa lapisan. Ini adalah keputusan yang disengaja untuk mempermudah pengenalan lapisan dengan cara yang lebih masuk akal untuk digunakan dengan codebase yang ada. Misalnya, menggunakan file reset.css adalah titik awal dan kasus penggunaan yang baik untuk lapisan cascade.

Aturan 3: !important membalik kekhususan cascade

Meskipun gaya berlapis kurang spesifik daripada gaya tanpa lapisan secara umum, penggunaan !important akan membalikkan hal ini. Dalam lapisan, deklarasi dengan aturan !important lebih spesifik daripada gaya tanpa lapisan.

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

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

Aturan 4: Pahami titik injeksi

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

Ini dapat berupa daftar, blok lapisan, atau impor. Jika Anda menempatkan @layer setelah daftar impor dengan layer(), tindakan ini tidak akan melakukan apa pun. Menempatkannya di bagian atas file akan membuatnya menetapkan urutan lapisan, dan membantu Anda melihat lapisan dalam arsitektur dengan jelas.

Aturan #5: Perhatikan kekhususan Anda

Dengan lapisan kaskade, 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 mengganti .pink di layer(utilities) jika: @layer utilities, components ditentukan. Meskipun merupakan bagian yang disengaja dari API, hal ini dapat membingungkan dan membuat frustrasi jika Anda tidak mengharapkannya.

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

Pelajari lapisan cascade lebih lanjut

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