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.
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.
Cara kerja @layer
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.
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.
Lapisan dan air terjun
Mari kita mundur selangkah dan melihat di mana {i>layer<i} digunakan dalam kaitannya dengan aliran yang lebih luas:
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: