Properti Kustom CSS Dalam Kaskade

Diterbitkan: 2022-03-10
Ringkasan cepat Dalam artikel ini, Miriam mempelajari lebih dalam spesifikasi 'CSS Custom Properties for Cascading Variables' untuk bertanya, “Mengapa mereka disebut properti khusus, bagaimana cara kerjanya dalam kaskade, dan apa lagi yang dapat kita lakukan dengannya ?” Melampaui metafora "variabel", properti kustom dapat memberikan cara baru untuk menyeimbangkan konteks dan isolasi dalam pola dan komponen CSS.

Bulan lalu, saya melakukan percakapan di Twitter tentang perbedaan antara gaya "cakupan" (dihasilkan dalam proses pembuatan) dan gaya "bersarang" asli CSS. Saya bertanya mengapa, secara anekdot, pengembang menghindari kekhususan pemilih ID, sambil merangkul "gaya cakupan" yang dihasilkan oleh JavaScript? Keith Grant menyarankan bahwa perbedaannya terletak pada keseimbangan kaskade* dan pewarisan, yaitu memberikan preferensi pada kedekatan daripada kekhususan. Mari lihat.

Kaskade

Kaskade CSS didasarkan pada tiga faktor:

  1. Kepentingan ditentukan oleh tanda !important , dan asal gaya (pengguna > penulis > browser)
  2. Spesifisitas dari pemilih yang digunakan (inline > ID > class > elemen)
  3. Source Order dari kode itu sendiri (yang terbaru diutamakan)

Kedekatan tidak disebutkan di mana pun — hubungan pohon DOM antara bagian pemilih. Paragraf di bawah keduanya akan berwarna merah, meskipun #inner p menggambarkan hubungan yang lebih dekat daripada #outer p untuk paragraf kedua:

Lihat Pena [Cascade: Specificity vs Proximity](https://codepen.io/smashingmag/pen/OexweJ/) oleh Miriam Suzanne.

Lihat Kaskade Pena: Kekhususan vs Kedekatan oleh Miriam Suzanne.
 <section> <p>This text is red</p> <div> <p>This text is also red!</p> </div> </section>
 #inner p { color: green; } #outer p { color: red; }

Kedua selektor memiliki spesifisitas yang sama, keduanya menggambarkan elemen p yang sama, dan tidak ada yang ditandai sebagai !important — jadi hasilnya hanya berdasarkan urutan sumber.

Lebih banyak setelah melompat! Lanjutkan membaca di bawah ini

BEM Dan Scoped Styles

Konvensi penamaan seperti BEM ("Block__Element—Modifier") digunakan untuk memastikan bahwa setiap paragraf "dicakup" hanya untuk satu induk, menghindari kaskade sepenuhnya. Paragraf "elemen" diberikan kelas unik khusus untuk konteks "blok" mereka:

Lihat Pena [BEM Selectors & Proximity](https://codepen.io/smashingmag/pen/qzPyeM/) oleh Miriam Suzanne.

Lihat Pen BEM Selectors & Proximity oleh Miriam Suzanne.
 <section class="outer"> <p class="outer__p">This text is red</p> <div class="inner"> <p class="inner__p">This text is green!</p> </div> </section>
 .inner__p { color: green; } .outer__p { color: red; }

Selektor ini masih memiliki kepentingan relatif, kekhususan, dan urutan sumber yang sama — tetapi hasilnya berbeda. Alat CSS “Cakupan” atau “modular” mengotomatiskan proses itu, menulis ulang CSS kami untuk kami, berdasarkan HTML. Dalam kode di bawah ini, setiap paragraf dicakup ke induk langsungnya:

Lihat Pena [Kedekatan Gaya Cakupan](https://codepen.io/smashingmag/pen/NZaLWN/) oleh Miriam Suzanne.

Lihat Kedekatan Gaya Pena Scoped oleh Miriam Suzanne.
 <section outer-scope> <p outer-scope>This text is red</p> <div outer-scope inner-scope> <p inner-scope>This text is green!</p> </div> </section>
 p[inner-scope] { color: green } p[outer-scope] { color: red; }

Warisan

Kedekatan bukan bagian dari kaskade, tetapi merupakan bagian dari CSS. Di situlah warisan menjadi penting. Jika kita menjatuhkan p dari penyeleksi kita, setiap paragraf akan mewarisi warna dari leluhur terdekatnya:

Lihat Pena [Warisan: Kekhususan vs Kedekatan](https://codepen.io/smashingmag/pen/mZBGyN/) oleh Miriam Suzanne.

Lihat Warisan Pena: Kekhususan vs Kedekatan oleh Miriam Suzanne.
 #inner { color: green; } #outer { color: red; }

Karena #inner dan #outer menggambarkan elemen yang berbeda, div dan section kita masing-masing, kedua properti warna diterapkan tanpa konflik. Elemen p bersarang tidak memiliki warna yang ditentukan, jadi hasilnya ditentukan oleh pewarisan (warna induk langsung) daripada cascade . Kedekatan diutamakan, dan nilai #inner menimpa #outer .

Tapi ada masalah: Untuk menggunakan warisan, kami menata semua yang ada di dalam section dan div kami. Kami ingin menargetkan warna paragraf secara khusus.

(Re-)Memperkenalkan Properti Kustom

Properti kustom memberikan solusi baru, browser-asli; mereka mewarisi seperti properti lainnya, tetapi mereka tidak harus digunakan di tempat yang didefinisikan . Menggunakan CSS biasa, tanpa konvensi penamaan atau alat pembuatan, kita dapat membuat gaya yang ditargetkan dan kontekstual, dengan kedekatan lebih diutamakan daripada kaskade:

Lihat Pena [Alat Peraga Kustom: Kekhususan vs Kedekatan](https://codepen.io/smashingmag/pen/gNGdaO/) oleh Miriam Suzanne.

Lihat Alat Peraga Kustom Pena: Kekhususan vs Kedekatan oleh Miriam Suzanne.
 p { color: var(--paragraph); } #inner { --paragraph: green; } #outer { --paragraph: red; }

Properti --paragraph kustom mewarisi seperti properti color , tetapi sekarang kita memiliki kendali atas bagaimana dan di mana nilai itu diterapkan. Properti --paragraph bertindak mirip dengan parameter yang dapat diteruskan ke komponen p , baik melalui pemilihan langsung (aturan-kekhususan) atau konteks (aturan-kedekatan).

Saya pikir ini mengungkapkan potensi properti khusus yang sering kita kaitkan dengan fungsi, mixin, atau komponen.

"Fungsi" dan Parameter Khusus

Fungsi, mixin, dan komponen semuanya didasarkan pada ide yang sama: kode yang dapat digunakan kembali, yang dapat dijalankan dengan berbagai parameter input untuk mendapatkan hasil yang konsisten namun dapat dikonfigurasi. Perbedaannya terletak pada apa yang mereka lakukan dengan hasil. Kita akan mulai dengan variabel gradien bergaris, dan kemudian kita dapat memperluasnya ke bentuk lain:

 html { --stripes: linear-gradient( to right, powderblue 20%, pink 20% 40%, white 40% 60%, pink 60% 80%, powderblue 80% ); }

Variabel itu didefinisikan pada elemen html root (bisa juga menggunakan :root , tapi itu menambahkan spesifisitas yang tidak perlu), jadi variabel bergaris kita akan tersedia di mana saja dalam dokumen. Kami dapat menerapkannya di mana saja gradien didukung:

Lihat Pena [Alat Peraga Kustom: Variabel](https://codepen.io/smashingmag/pen/NZwrrm/) oleh Miriam Suzanne.

Lihat Alat Peraga Kustom Pena: Variabel oleh Miriam Suzanne.
 body { background-image: var(--stripes); }

Menambahkan Parameter

Fungsi digunakan seperti variabel, tetapi menentukan parameter untuk mengubah output. Kita dapat memperbarui variabel --stripes menjadi lebih seperti fungsi dengan mendefinisikan beberapa variabel seperti parameter di dalamnya. Saya akan mulai dengan mengganti to right dengan var(--stripes-angle) , untuk membuat parameter pengubah sudut:

 html { --stripes: linear-gradient( var(--stripes-angle), powderblue 20%, pink 20% 40%, white 40% 60%, pink 60% 80%, powderblue 80% ); }

Ada parameter lain yang bisa kita buat, tergantung pada tujuan apa fungsi itu dimaksudkan untuk dilayani. Haruskah kita mengizinkan pengguna untuk memilih warna garis mereka sendiri? Jika demikian, apakah fungsi kita menerima 5 parameter warna yang berbeda atau hanya 3 yang akan keluar-masuk seperti yang kita miliki sekarang? Apakah kita ingin membuat parameter untuk penghentian warna juga? Setiap parameter yang kami tambahkan memberikan lebih banyak penyesuaian dengan mengorbankan kesederhanaan dan konsistensi.

Tidak ada jawaban yang benar secara universal untuk keseimbangan itu — beberapa fungsi perlu lebih fleksibel, dan yang lain perlu lebih berpendirian. Abstraksi ada untuk memberikan konsistensi dan keterbacaan dalam kode Anda, jadi mundur selangkah dan tanyakan apa tujuan Anda. Apa yang benar-benar perlu disesuaikan, dan di mana konsistensi harus ditegakkan? Dalam beberapa kasus, mungkin lebih membantu untuk memiliki dua fungsi yang memiliki opini, daripada satu fungsi yang dapat disesuaikan sepenuhnya.

Untuk menggunakan fungsi di atas, kita perlu memasukkan nilai untuk parameter --stripes-angle , dan menerapkan output ke properti output CSS, seperti background-image :

 /* in addition to the code above… */ html { --stripes-angle: 75deg; background-image: var(--stripes); } 

Lihat Pena [Alat Peraga Kustom: Fungsi](https://codepen.io/smashingmag/pen/BgwOjj/) oleh Miriam Suzanne.

Lihat Alat Peraga Kustom Pena: Fungsi oleh Miriam Suzanne.

Diwarisi Versus Universal

Saya mendefinisikan fungsi --stripes pada elemen html karena kebiasaan. Properti kustom mewarisi, dan saya ingin fungsi saya tersedia di mana-mana, jadi masuk akal untuk meletakkannya di elemen root. Itu berfungsi dengan baik untuk mewarisi variabel seperti --brand-color: blue , jadi kita mungkin juga berharap itu berfungsi untuk "fungsi" kita juga. Tetapi jika kami mencoba menggunakan fungsi ini lagi pada pemilih bersarang, itu tidak akan berfungsi:

Lihat Pena [Alat Peraga Kustom: Pewarisan Fungsi Gagal](https://codepen.io/smashingmag/pen/RzjRrM/) oleh Miriam Suzanne.

Lihat Alat Peraga Kustom Pena: Pewarisan Fungsi Gagal oleh Miriam Suzanne.
 div { --stripes-angle: 90deg; background-image: var(--stripes); }

--stripes-angle baru diabaikan sepenuhnya. Ternyata kita tidak bisa mengandalkan warisan untuk fungsi yang perlu dihitung ulang. Itu karena setiap nilai properti dihitung sekali per elemen (dalam kasus kami, elemen root html ), dan kemudian nilai yang dihitung diwariskan . Dengan mendefinisikan fungsi kita di root dokumen, kita tidak membuat seluruh fungsi tersedia untuk turunan — hanya hasil yang dihitung dari fungsi kita.

Itu masuk akal jika Anda membingkainya dalam hal parameter cascading --stripes-angle . Seperti properti CSS yang diwarisi, properti ini tersedia untuk turunan tetapi tidak untuk leluhur. Nilai yang kita tetapkan pada div bersarang tidak tersedia untuk fungsi yang kita definisikan pada ancestor root html . Untuk membuat fungsi yang tersedia secara universal yang akan menghitung ulang pada elemen apa pun, kita harus mendefinisikannya pada setiap elemen:

Lihat Pena [Alat Peraga Kustom: Fungsi Universal](https://codepen.io/smashingmag/pen/agLaNj/) oleh Miriam Suzanne.

Lihat Alat Peraga Kustom Pena: Fungsi Universal oleh Miriam Suzanne.
 * { --stripes: linear-gradient( var(--stripes-angle), powderblue 20%, pink 20% 40%, white 40% 60%, pink 60% 80%, powderblue 80% ); }

Selektor universal membuat fungsi kita tersedia di mana-mana, tetapi kita dapat mendefinisikannya lebih sempit jika kita mau. Yang penting adalah bahwa ia hanya dapat menghitung ulang di mana ia didefinisikan secara eksplisit. Berikut adalah beberapa alternatif:

 /* make the function available to elements with a given selector */ .stripes { --stripes: /* etc… */; } /* make the function available to elements nested inside a given selector */ .stripes * { --stripes: /* etc… */; } /* make the function available to siblings following a given selector */ .stripes ~ * { --stripes: /* etc… */; } 

Lihat Pena [Alat Peraga Kustom: Fungsi Cakupan](https://codepen.io/smashingmag/pen/JQMvGM/) oleh Miriam Suzanne.

Lihat Alat Peraga Kustom Pena: Fungsi Cakupan oleh Miriam Suzanne.

Ini dapat diperluas dengan logika pemilih apa pun yang tidak bergantung pada pewarisan.

Parameter Gratis Dan Nilai Pengganti

Dalam contoh kita di atas, var(--stripes-angle) tidak memiliki nilai dan tidak ada fallback. Tidak seperti variabel Sass atau JS yang harus didefinisikan atau dipakai sebelum dipanggil, properti kustom CSS dapat dipanggil tanpa pernah didefinisikan. Ini menciptakan variabel "bebas", mirip dengan parameter fungsi yang dapat diwarisi dari konteksnya.

Kami akhirnya dapat mendefinisikan variabel pada html atau :root (atau leluhur lainnya) untuk menetapkan nilai yang diwariskan, tetapi pertama-tama kami perlu mempertimbangkan fallback jika tidak ada nilai yang ditentukan. Ada beberapa opsi, tergantung pada perilaku apa yang kita inginkan

  1. Untuk parameter "wajib", kami tidak menginginkan fallback. Apa adanya, fungsi tidak akan melakukan apa pun sampai --stripes-angle didefinisikan.
  2. Untuk parameter “opsional”, kami dapat memberikan nilai fallback dalam fungsi var() . Setelah nama variabel, kami menambahkan koma, diikuti dengan nilai default:
 var(--stripes-angle, 90deg)

Setiap fungsi var() hanya dapat memiliki satu fallback — jadi koma tambahan apa pun akan menjadi bagian dari nilai itu. Itu memungkinkan untuk memberikan default kompleks dengan koma internal:

 html { /* Computed: Hevetica, Ariel, sans-serif */ font-family: var(--sans-family, Hevetica, Ariel, sans-serif); /* Computed: 0 -1px 0 white, 0 1px 0 black */ test-shadow: var(--shadow, 0 -1px 0 white, 0 1px 0 black); }

Kami juga dapat menggunakan variabel bersarang untuk membuat aturan kaskade kami sendiri, memberikan prioritas yang berbeda untuk nilai yang berbeda:

 var(--stripes-angle, var(--global-default-angle, 90deg))
  1. Pertama, coba parameter eksplisit kami ( --stripes-angle );
  2. Kembali ke "default pengguna" global ( --user-default-angle ) jika tersedia;
  3. Terakhir, mundur ke "default pabrik" kami (90deg ).

Lihat Pena [Alat Peraga Kustom: Nilai Pengganti](https://codepen.io/smashingmag/pen/jjGvVm/) oleh Miriam Suzanne.

Lihat Alat Peraga Kustom Pena: Nilai Pengganti oleh Miriam Suzanne.

Dengan menyetel nilai fallback di var() daripada mendefinisikan properti kustom secara eksplisit, kami memastikan bahwa tidak ada batasan spesifisitas atau kaskade pada parameter. Semua parameter *-angle "bebas" untuk diwarisi dari konteks apa pun.

Fallback Browser Versus Fallback Variabel

Saat kita menggunakan variabel, ada dua jalur mundur yang perlu kita ingat:

  1. Nilai apa yang harus digunakan oleh browser tanpa dukungan variabel?
  2. Nilai apa yang harus digunakan oleh browser yang mendukung variabel, ketika variabel tertentu hilang atau tidak valid?
 p { color: blue; color: var(--paragraph); }

Sementara browser lama akan mengabaikan properti deklarasi variabel, dan mundur ke blue — browser modern akan membaca keduanya dan menggunakan yang terakhir. var(--paragraph) kami mungkin tidak didefinisikan, tetapi valid dan akan menimpa properti sebelumnya, jadi browser dengan dukungan variabel akan mundur ke nilai awal atau warisan, seolah-olah menggunakan kata kunci yang unset .

Itu mungkin tampak membingungkan pada awalnya, tetapi ada alasan bagus untuk itu. Yang pertama adalah teknis: mesin browser menangani sintaks yang tidak valid atau tidak dikenal pada "waktu parse" (yang terjadi lebih dulu), tetapi variabel tidak diselesaikan sampai "waktu nilai yang dihitung" (yang terjadi kemudian).

  1. Pada waktu parse, deklarasi dengan sintaks yang tidak valid diabaikan sepenuhnya — kembali ke deklarasi sebelumnya. Ini adalah jalur yang akan diikuti oleh browser lama. Browser modern mendukung sintaks variabel, jadi deklarasi sebelumnya dibuang.
  2. Pada waktu nilai yang dihitung, variabel dikompilasi sebagai tidak valid, tetapi sudah terlambat — deklarasi sebelumnya sudah dibuang. Menurut spesifikasi, nilai variabel yang tidak valid diperlakukan sama dengan unset :

Lihat Pena [Alat Peraga Kustom: Tidak Valid/Tidak Didukung vs Tidak Terdefinisi](https://codepen.io/smashingmag/pen/VJMGbJ/) oleh Miriam Suzanne.

Lihat Alat Peraga Kustom Pena: Tidak Valid/Tidak Didukung vs Tidak Ditentukan oleh Miriam Suzanne.
 html { color: red; /* ignored as *invalid syntax* by all browsers */ /* - old browsers: red */ /* - new browsers: red */ color: not a valid color; color: var(not a valid variable name); /* ignored as *invalid syntax* by browsers without var support */ /* valid syntax, but invalid *values* in modern browsers */ /* - old browsers: red */ /* - new browsers: unset (black) */ --invalid-value: not a valid color value; color: var(--undefined-variable); color: var(--invalid-value); }

Ini juga bagus untuk kita sebagai penulis, karena memungkinkan kita untuk bermain dengan fallback yang lebih kompleks untuk browser yang mendukung variabel, dan menyediakan fallback sederhana untuk browser lama. Lebih baik lagi, itu memungkinkan kita untuk menggunakan status null / undefined untuk mengatur parameter yang diperlukan. Ini menjadi sangat penting jika kita ingin mengubah fungsi menjadi mixin atau komponen.

Properti Kustom "Mixin"

Di Sass, fungsi mengembalikan nilai mentah, sementara mixin umumnya mengembalikan keluaran CSS aktual dengan pasangan nilai properti. Saat kita mendefinisikan properti --stripes universal, tanpa menerapkannya ke output visual apa pun, hasilnya seperti fungsi. Kita dapat membuatnya berperilaku lebih seperti mixin, dengan mendefinisikan output secara universal juga:

 * { --stripes: linear-gradient( var(--stripes-angle), powderblue 20%, pink 20% 40%, white 40% 60%, pink 60% 80%, powderblue 80% ); background-image: var(--stripes); }

Selama --stripes-angle tetap tidak valid atau tidak ditentukan, mixin gagal dikompilasi, dan tidak ada background-image akan diterapkan. Jika kita menetapkan sudut yang valid pada elemen apa pun, fungsi akan menghitung dan memberi kita latar belakang:

 div { --stripes-angle: 30deg; /* generates the background */ }

Sayangnya, nilai parameter itu akan mewarisi, jadi definisi saat ini membuat latar belakang pada div dan semua turunan . Untuk memperbaikinya, kita harus memastikan nilai --stripes-angle tidak diturunkan, dengan meletakkannya ke nilai initial (atau nilai yang tidak valid) pada setiap elemen. Kita dapat melakukannya pada pemilih universal yang sama:

Lihat Pena [Alat Peraga Kustom: Mixin](https://codepen.io/smashingmag/pen/ZdXMJx/) oleh Miriam Suzanne.

Lihat Alat Peraga Kustom Pena: Mixin oleh Miriam Suzanne.
 * { --stripes-angle: initial; --stripes: /* etc… */; background-image: var(--stripes); }

Gaya Inline Aman

Dalam beberapa kasus, kita memerlukan parameter untuk disetel secara dinamis dari CSS luar — berdasarkan data dari server back-end atau kerangka kerja front-end. Dengan properti khusus, kami dapat dengan aman mendefinisikan variabel dalam HTML kami tanpa mengkhawatirkan masalah kekhususan yang biasa terjadi:

Lihat Pena [Alat Peraga Kustom: Mixin + Inline Style](https://codepen.io/smashingmag/pen/qzPMPv/) oleh Miriam Suzanne.

Lihat Alat Peraga Kustom Pena: Mixin + Inline Style oleh Miriam Suzanne.
 <div>...</div>

Gaya sebaris memiliki spesifisitas yang tinggi, dan sangat sulit untuk ditimpa — tetapi dengan properti khusus, kami memiliki opsi lain: abaikan saja. Jika kita mengatur div ke background-image: none (misalnya) variabel sebaris itu tidak akan berpengaruh. Untuk membuatnya lebih jauh, kita dapat membuat variabel perantara:

 * { --stripes-angle: var(--stripes-angle-dynamic, initial); }

Sekarang kita memiliki opsi untuk mendefinisikan --stripes-angle-dynamic di HTML, atau mengabaikannya, dan mengatur --stripes-angle langsung di stylesheet kita.

Lihat Pena [Alat Peraga Kustom: Mixin + Inline / Override](https://codepen.io/smashingmag/pen/ZdXMao/) oleh Miriam Suzanne.

Lihat Alat Peraga Kustom Pena: Mixin + Inline / Override oleh Miriam Suzanne.

Nilai Preset

Untuk nilai yang lebih kompleks, atau pola umum yang ingin kami gunakan kembali, kami juga dapat menyediakan beberapa variabel prasetel untuk dipilih:

 * { --tilt-down: 6deg; --tilt-up: -6deg; }

Dan gunakan preset itu, daripada mengatur nilainya secara langsung:

 <div>...</div> 

Lihat Pena [Alat Peraga Kustom: Mixin + Preset](https://codepen.io/smashingmag/pen/LKemZm/) oleh Miriam Suzanne.

Lihat Pen Custom Props: Mixin + Presets oleh Miriam Suzanne.

Ini bagus untuk membuat bagan dan grafik berdasarkan data dinamis, atau bahkan menyusun agenda harian.

Lihat Pena [Grafik batang dalam kisi + variabel CSS](https://codepen.io/smashingmag/pen/wLrEyg/) oleh Miriam Suzanne.

Lihat bagan Pen Bar di kotak CSS + variabel oleh Miriam Suzanne.

Komponen Kontekstual

Kami juga dapat membingkai ulang "mixin" kami sebagai "komponen" dengan menerapkannya ke pemilih eksplisit, dan menjadikan parameter opsional. Daripada mengandalkan ada atau tidaknya --stripes-angle untuk mengaktifkan output kita, kita bisa mengandalkan ada atau tidaknya pemilih komponen. Itu memungkinkan kita untuk menetapkan nilai fallback dengan aman:

Lihat Pena [Alat Peraga Kustom: Komponen](https://codepen.io/smashingmag/pen/QXqVmM/) oleh Miriam Suzanne.

Lihat Alat Peraga Kustom Pena: Komponen oleh Miriam Suzanne.
 [data-stripes] { --stripes: linear-gradient( var(--stripes-angle, to right), powderblue 20%, pink 20% 40%, white 40% 60%, pink 60% 80%, powderblue 80% ); background-image: var(--stripes); }

Dengan meletakkan fallback di dalam fungsi var() , kita dapat membiarkan --stripes-angle tidak terdefinisi dan “bebas” untuk mewarisi nilai dari luar komponen. Ini adalah cara yang bagus untuk mengekspos aspek tertentu dari gaya komponen ke input kontekstual. Bahkan gaya "tercakup" yang dihasilkan oleh kerangka kerja JS (atau dicakup di dalam shadow-DOM, seperti ikon SVG) dapat menggunakan pendekatan ini untuk mengekspos parameter tertentu untuk pengaruh luar.

Komponen Terisolasi

Jika kita tidak ingin mengekspos parameter untuk pewarisan, kita dapat mendefinisikan variabel dengan nilai default:

 [data-stripes] { --stripes-angle: to right; --stripes: linear-gradient( var(--stripes-angle, to right), powderblue 20%, pink 20% 40%, white 40% 60%, pink 60% 80%, powderblue 80% ); background-image: var(--stripes); }

Komponen-komponen ini juga akan berfungsi dengan kelas, atau pemilih valid lainnya, tetapi saya memilih atribut data- untuk membuat namespace untuk pengubah apa pun yang kita inginkan:

 [data-stripes='vertical'] { --stripes-angle: to bottom; } [data-stripes='horizontal'] { --stripes-angle: to right; } [data-stripes='corners'] { --stripes-angle: to bottom right; } 

Lihat Pena [Alat Peraga Kustom: Komponen Terisolasi](https://codepen.io/smashingmag/pen/agLaGX/) oleh Miriam Suzanne.

Lihat Alat Peraga Kustom Pena: Komponen Terisolasi oleh Miriam Suzanne.

Selektor dan Parameter

Saya sering berharap dapat menggunakan atribut data untuk menetapkan variabel — fitur yang didukung oleh spesifikasi attr() CSS3, tetapi belum diterapkan di browser mana pun (lihat tab sumber daya untuk masalah terkait di setiap browser). Itu akan memungkinkan kita untuk lebih dekat mengaitkan pemilih dengan parameter tertentu:

 <div data-stripes="30deg">...</div> /* Part of the CSS3 spec, but not yet supported */ /* attr( , ) */ [data-stripes] { --stripes-angle: attr(data-stripes angle, to right); } <div data-stripes="30deg">...</div> /* Part of the CSS3 spec, but not yet supported */ /* attr( , ) */ [data-stripes] { --stripes-angle: attr(data-stripes angle, to right); } <div data-stripes="30deg">...</div> /* Part of the CSS3 spec, but not yet supported */ /* attr( , ) */ [data-stripes] { --stripes-angle: attr(data-stripes angle, to right); }

Sementara itu, kita dapat mencapai sesuatu yang serupa dengan menggunakan atribut style :

Lihat Pena [Alat Peraga Kustom: Pemilih Gaya](https://codepen.io/smashingmag/pen/PrJdBG/) oleh Miriam Suzanne.

Lihat Pen Custom Props: Style Selectors oleh Miriam Suzanne.
 <div>...</div> /* The `*=` atttribute selector will match a string anywhere in the attribute */ [style*='--stripes-angle'] { /* Only define the function where we want to call it */ --stripes: linear-gradient(…); }

Pendekatan ini paling berguna ketika kita ingin memasukkan properti lain selain parameter yang disetel. Misalnya, menyetel area kisi juga dapat menambahkan padding dan latar belakang:

 [style*='--grid-area'] { background-color: white; grid-area: var(--grid-area, auto / 1 / auto / -1); padding: 1em; }

Kesimpulan

Saat kita mulai menggabungkan semua bagian ini, menjadi jelas bahwa properti kustom jauh melampaui kasus penggunaan variabel umum yang kita kenal. Kami tidak hanya dapat menyimpan nilai, dan memasukkannya ke kaskade — tetapi kami dapat menggunakannya untuk memanipulasi kaskade dengan cara baru, dan membuat komponen yang lebih cerdas langsung di CSS.

Hal ini mengharuskan kami untuk memikirkan kembali banyak alat yang kami andalkan di masa lalu — mulai dari konvensi penamaan seperti SMACSS dan BEM, hingga gaya “tercakup” dan CSS-in-JS. Banyak dari alat tersebut membantu mengatasi kekhususan, atau mengelola gaya dinamis dalam bahasa lain — kasus penggunaan yang sekarang dapat kita atasi secara langsung dengan properti kustom. Gaya dinamis yang sering kita hitung di JS, sekarang dapat ditangani dengan meneruskan data mentah ke CSS.

Pada awalnya, perubahan ini mungkin terlihat sebagai "tambahan kompleksitas" — karena kita tidak terbiasa melihat logika di dalam CSS. Dan, seperti semua kode, over-engineering bisa menjadi bahaya nyata. Tetapi saya berpendapat bahwa dalam banyak kasus, kita dapat menggunakan kekuatan ini untuk tidak menambah kompleksitas, tetapi untuk memindahkan kompleksitas dari alat dan konvensi pihak ketiga, kembali ke bahasa inti desain web, dan (lebih penting) kembali ke peramban. Jika gaya kita memerlukan perhitungan, perhitungan itu harus hidup di dalam CSS kita.

Semua ide ini dapat diambil lebih jauh. Properti khusus baru mulai melihat adopsi yang lebih luas, dan kami baru mulai menggores permukaan dari apa yang mungkin. Saya senang melihat ke mana arahnya, dan apa lagi yang muncul dari orang-orang. Selamat bersenang-senang!

Bacaan lebih lanjut

  • “Saatnya Mulai Menggunakan Properti Kustom CSS,” Serg Hospodarets
  • “Panduan Strategi Untuk Properti Kustom CSS,” Michael Riethmuller