Cara Mengonfigurasi Skema Warna Aplikasi Dengan CSS Custom Properties
Diterbitkan: 2022-03-10Variabel adalah alat dasar yang membantu mengatur warna pada sebuah proyek. Untuk waktu yang lama, para insinyur front-end menggunakan variabel praprosesor untuk mengonfigurasi warna pada sebuah proyek. Namun sekarang, banyak pengembang lebih memilih mekanisme asli modern untuk mengatur variabel warna: Properti Kustom CSS. Keuntungan terpentingnya dibandingkan variabel praprosesor adalah variabel tersebut bekerja secara realtime, bukan pada tahap kompilasi proyek, dan memiliki dukungan untuk model kaskade yang memungkinkan Anda menggunakan pewarisan dan pendefinisian ulang nilai dengan cepat.
Saat Anda mencoba mengatur skema warna aplikasi, Anda selalu dapat menempatkan semua properti kustom yang berhubungan dengan warna di bagian akar, memberi nama, dan menggunakannya di semua tempat yang diperlukan.
Lihat Pena [Properti Kustom untuk Warna](https://codepen.io/smashingmag/pen/RwaNqxW) oleh Artur Basak.
Itu pilihan, tetapi apakah itu membantu Anda menyelesaikan masalah tema aplikasi, pelabelan putih, penyegaran merek, atau mengatur mode terang atau gelap? Bagaimana jika Anda perlu menyesuaikan skema warna untuk meningkatkan kontras? Dengan pendekatan saat ini, Anda harus memperbarui setiap nilai dalam variabel Anda.
Dalam artikel ini, saya ingin menyarankan pendekatan yang lebih fleksibel dan tahan tentang cara membagi variabel warna menggunakan properti khusus, yang dapat memecahkan banyak masalah ini.
Atur Palet Warna
Pewarnaan situs web apa pun dimulai dengan pengaturan skema warna. Skema semacam itu didasarkan pada roda warna. Biasanya, hanya beberapa warna primer yang menjadi dasar palet, sisanya adalah warna turunan — nada dan nada tengah. Paling sering, palet statis dan tidak berubah saat aplikasi web berjalan.
Menurut teori warna, hanya ada beberapa opsi untuk skema warna:
- Skema monokromatik (satu warna primer)
- Skema komplementer (dua warna primer)
- Skema triad (tiga warna primer)
- Skema tetradik (empat warna primer)
- Pola yang berdekatan (dua atau tiga warna primer)
Sebagai contoh saya, saya akan membuat skema warna triad menggunakan layanan Paletton:

Saya sekarang memiliki tiga warna utama. Atas dasar ini, saya akan menghitung nada dan nada tengah (format HSL dalam kombinasi dengan fungsi calc
adalah alat yang sangat berguna untuk ini). Dengan mengubah nilai lightness, saya dapat menghasilkan beberapa warna tambahan untuk palet.
Lihat Pena [Palette HSL](https://codepen.io/smashingmag/pen/OJNPaQW) oleh Artur Basak.
Sekarang jika palet diubah, maka hanya perlu mengubah nilai warna primer. Sisanya akan dihitung ulang secara otomatis.
Jika Anda lebih suka format HEX atau RGB, maka itu tidak masalah; palet dapat dibentuk pada tahap kompilasi proyek dengan fungsi yang sesuai dari praprosesor (misalnya dengan SCSS dan fungsi color-adjust
). Seperti yang telah saya sebutkan sebelumnya, lapisan ini sebagian besar statis; sangat jarang palet dapat diubah dalam aplikasi yang sedang berjalan. Itu sebabnya kami dapat menghitungnya dengan praprosesor.
Catatan : Saya sarankan juga menghasilkan HEX literal dan RGB untuk setiap warna. Ini akan memungkinkan bermain dengan saluran alfa di masa mendatang.
Lihat Pena [SCSS Palette](https://codepen.io/smashingmag/pen/oNxgQqv) oleh Artur Basak.
Level palet adalah satu-satunya level di mana warna dikodekan secara langsung dalam nama variabel, yaitu kita dapat mengidentifikasi warna secara unik dengan membaca namanya.
Tentukan Tema Atau Warna Fungsional
Setelah palet selesai, langkah selanjutnya adalah tingkat warna fungsional . Pada tingkat ini, nilai warna tidak begitu penting seperti tujuannya, fungsi yang dilakukannya, dan apa yang sebenarnya diwarnai. Misalnya, warna merek utama atau aplikasi, warna batas, warna teks pada latar belakang gelap, warna teks pada latar belakang terang, warna latar tombol, warna tautan, warna tautan arahkan kursor, warna teks petunjuk, dan sebagainya .
Ini adalah hal yang sangat umum untuk hampir semua situs web atau aplikasi. Kita dapat mengatakan bahwa warna tersebut bertanggung jawab atas tema warna tertentu dari aplikasi. Juga, nilai-nilai variabel tersebut diambil secara ketat dari palet. Dengan demikian, kita dapat dengan mudah mengubah tema aplikasi hanya dengan mengoperasikan palet warna yang berbeda.
Di bawah ini, saya telah membuat tiga kontrol UI khas: tombol, tautan, dan bidang input. Mereka diwarnai menggunakan variabel fungsional yang berisi nilai dari palet yang saya buat sebelumnya di atas. Variabel fungsional utama yang bertanggung jawab atas tema aplikasi (merek bersyarat) adalah variabel warna primer.
Dengan menggunakan tiga tombol di bagian atas, Anda dapat mengganti tema (mengubah warna merek untuk kontrol). Perubahan terjadi dengan menggunakan CSSOM API (setProperty) yang sesuai.
Lihat Pena [Warna Fungsional](https://codepen.io/smashingmag/pen/poyvQLL) oleh Artur Basak.
Pendekatan ini nyaman tidak hanya untuk tema tetapi juga untuk mengonfigurasi halaman web individual. Misalnya, di situs web zubry.by, saya menggunakan stylesheet umum dan variabel fungsional --page-color
untuk mewarnai logo, heading, kontrol, dan pemilihan teks untuk semua halaman. Dan dalam gaya masing-masing halaman, saya baru saja mendefinisikan ulang variabel ini untuk mengatur halaman masing-masing warna utama.

Gunakan Warna Komponen
Proyek web besar selalu mengandung dekomposisi; kami membagi semuanya menjadi komponen-komponen kecil dan menggunakannya kembali di banyak tempat. Setiap komponen biasanya memiliki gayanya sendiri yang berarti tidak masalah apa yang kami gunakan untuk menguraikan Modul BEM atau CSS, atau pendekatan lain; penting bahwa setiap potongan kode tersebut dapat disebut lingkup lokal dan digunakan kembali.
Secara umum, saya melihat gunanya menggunakan variabel warna pada tingkat komponen dalam dua kasus.
Yang pertama adalah ketika komponen yang menurut panduan gaya aplikasi diulang dengan pengaturan yang berbeda, misalnya tombol untuk kebutuhan yang berbeda seperti tombol primer (merek), tombol sekunder, tersier, dan sebagainya.

Yang kedua adalah ketika komponen yang memiliki beberapa status dengan warna berbeda, misalnya tombol hover, status aktif dan fokus; keadaan normal dan tidak valid untuk bidang input atau pilih, dan seterusnya.
Kasus yang lebih jarang terjadi ketika variabel komponen mungkin berguna adalah fungsi "label putih". "Label putih" adalah fitur layanan yang memungkinkan pengguna untuk menyesuaikan atau merek beberapa bagian dari antarmuka pengguna untuk meningkatkan pengalaman berinteraksi dengan klien mereka. Misalnya, dokumen elektronik yang dibagikan pengguna dengan pelanggannya melalui layanan atau template email. Dalam hal ini, variabel pada level komponen akan membantu mengonfigurasi komponen tertentu secara terpisah dari tema warna aplikasi lainnya.
Pada contoh di bawah ini, saya sekarang telah menambahkan kontrol untuk menyesuaikan warna tombol (merek) utama. Dengan menggunakan variabel warna pada level komponen, kita dapat mengonfigurasi kontrol UI secara terpisah satu sama lain.
Lihat Pena [Warna Komponen](https://codepen.io/smashingmag/pen/LYNEXdw) oleh Artur Basak.

Bagaimana Cara Menentukan Level Apa yang Dimiliki Variabel?
Saya menemukan pertanyaan tentang bagaimana memahami apa yang dapat diletakkan di root (tema atau tingkat fungsional), dan apa yang harus ditinggalkan pada tingkat komponen. Ini adalah pertanyaan bagus yang sulit dijawab tanpa melihat situasi yang sedang Anda hadapi.
Sayangnya, pendekatan yang sama seperti dalam pemrograman tidak bekerja dengan warna dan gaya, jika kita melihat tiga bagian kode yang identik maka kita perlu memfaktorkannya kembali.
Warna dapat diulang dari komponen ke komponen, tetapi ini tidak berarti bahwa itu adalah aturan. Tidak ada hubungan antara komponen-komponen tersebut. Misalnya, batas bidang input dan latar belakang tombol utama. Ya, dalam contoh saya di atas itu yang terjadi, tetapi mari kita periksa contoh berikut:
Lihat Pena [Pemisahan Warna: Hanya Palet](https://codepen.io/smashingmag/pen/YzqPRLX) oleh Artur Basak.
Warna abu-abu gelap diulang — ini adalah batas bidang input, warna isian ikon tutup, dan latar belakang tombol sekunder. Tetapi komponen-komponen ini sama sekali tidak terhubung satu sama lain. Jika warna batas bidang input berubah, maka kami tidak akan mengubah latar belakang tombol sekunder. Untuk kasus seperti itu kita harus menyimpan di sini hanya variabel dari palet.

Bagaimana dengan hijau? Kita dapat dengan jelas mendefinisikannya sebagai warna primer atau merek, kemungkinan besar, jika warna tombol utama berubah, maka warna tautan dan header tingkat pertama juga akan berubah.
Bagaimana dengan merah? Status bidang input, pesan kesalahan, dan tombol destruktif yang tidak valid akan memiliki warna yang sama di seluruh level aplikasi. Ini adalah sebuah pola. Sekarang saya dapat mendefinisikan beberapa variabel fungsional umum di bagian root:
Lihat Pena [Pemisahan Warna: Tingkat Fungsional](https://codepen.io/smashingmag/pen/MWyYzGX) oleh Artur Basak.
Mengenai tingkat warna komponen, kita dapat dengan mudah mengidentifikasi komponen yang dapat dikustomisasi menggunakan properti kustom.
Tombol diulang dengan pengaturan yang berbeda, warna latar belakang dan teks untuk kasus penggunaan yang berbeda berubah — kasus primer, sekunder, tersier, destruktif atau negatif.
Bidang input memiliki dua status — salah dan normal, di mana warna latar belakang dan batas berbeda. Jadi, mari kita masukkan pengaturan ini ke dalam variabel warna pada tingkat komponen yang sesuai.
Untuk komponen lainnya, tidak perlu mendefinisikan variabel warna lokal, ini akan berlebihan.
Lihat Pena [Pemisahan Warna: Level Komponen](https://codepen.io/smashingmag/pen/BaKyGVR) oleh Artur Basak.
Anda perlu mempelajari bahasa pola proyek Anda, yang mungkin sedang dikembangkan oleh tim desain dan UX. Insinyur harus sepenuhnya memahami seluruh konsep bahasa visual, hanya dengan demikian kita dapat menentukan apa yang umum dan harus hidup pada tingkat fungsional, dan apa yang harus tetap berada dalam lingkup visibilitas lokal.
Tapi semuanya tidak begitu rumit, ada hal-hal yang jelas. Latar belakang umum halaman, latar belakang, dan warna teks utama, dalam banyak kasus inilah yang menentukan tema aplikasi Anda. Sangat mudah untuk mengumpulkan hal-hal seperti itu yang bertanggung jawab untuk konfigurasi mode tertentu (seperti mode gelap atau terang).
Mengapa Tidak Menempatkan Semuanya Di Bagian Root?
Saya memiliki pengalaman seperti itu. Pada proyek Lition, tim dan saya dihadapkan pada kenyataan bahwa kami perlu mendukung IE11 untuk aplikasi web, tetapi tidak untuk situs web dan arahan. Kit UI umum digunakan di antara proyek, dan kami memutuskan untuk meletakkan semua variabel di root, ini akan memungkinkan kami untuk mendefinisikannya kembali di level mana pun.
Dan juga dengan pendekatan ini untuk aplikasi web dan kasus IE11, kami hanya meneruskan kode melalui plugin pasca-prosesor berikut dan mengubah variabel ini menjadi literal untuk semua komponen UI dalam proyek. Trik ini hanya mungkin jika semua variabel didefinisikan di bagian root karena post-processor tidak dapat memahami spesifikasi model kaskade.

Sekarang saya mengerti bahwa ini bukan cara yang benar. Pertama, jika Anda memasukkan warna komponen ke bagian root, maka Anda melanggar prinsip pemisahan kekhawatiran. Akibatnya, Anda dapat berakhir dengan CSS yang berlebihan di stylesheet. Misalnya, Anda memiliki folder komponen di mana setiap komponen memiliki gayanya sendiri. Anda juga memiliki lembar gaya umum tempat Anda menjelaskan variabel warna di bagian akar. Anda memutuskan untuk menghapus komponen tombol; dalam hal ini, Anda harus ingat untuk juga menghapus variabel yang terkait dengan tombol dari file gaya umum.
Kedua, ini bukan solusi terbaik dalam hal kinerja. Ya, perubahan warna hanya menyebabkan proses pengecatan ulang, bukan reflow/tata letak, ini sendiri tidak terlalu mahal, tetapi ketika Anda membuat beberapa perubahan pada tingkat tertinggi, Anda akan menggunakan lebih banyak sumber daya untuk memeriksa seluruh pohon daripada saat ini perubahan berada di area lokal kecil. Saya sarankan membaca tolok ukur kinerja variabel CSS dari Lisi Linhart untuk lebih jelasnya.
Pada proyek saya saat ini Tispr, tim dan saya menggunakan split dan tidak membuang semuanya di root, pada level tinggi hanya palet dan warna fungsional. Juga, kami tidak takut dengan IE11, karena masalah ini diselesaikan dengan polyfill yang sesuai. Cukup instal modul npm ie11-custom-properties dan impor perpustakaan ke dalam bundel JS aplikasi Anda:
// Use ES6 syntax import "ie11-custom-properties"; // or CommonJS require('ie11-custom-properties');
Atau tambahkan modul dengan tag skrip:
<script async src="./node_modules/ie11-custom-properties/ie11CustomProperties.js">
Juga, Anda dapat menambahkan perpustakaan tanpa npm melalui CDN. Pekerjaan polyfill ini didasarkan pada fakta bahwa IE11 memiliki dukungan minimal untuk properti kustom, di mana properti dapat ditentukan dan dibaca berdasarkan kaskade. Ini tidak mungkin dengan properti yang dimulai dengan tanda hubung ganda, tetapi mungkin dengan tanda hubung tunggal (mekanismenya mirip dengan awalan vendor). Anda dapat membaca lebih lanjut tentang ini di dokumentasi repositori, serta berkenalan dengan beberapa batasan. Browser lain akan mengabaikan polyfill ini.
Di bawah ini adalah palet aplikasi web Tispr serta kontrol fungsi "label putih" untuk dokumen elektronik (seperti kontrak pengguna, faktur, atau proposal).


Mengapa Tidak Menyimpan Variabel Warna Di Sisi JavaScript?
Pertanyaan masuk akal lainnya: mengapa tidak menyimpan palet dan variabel fungsi dalam kode JavaScript? Ini juga dapat diubah secara dinamis dan kemudian mendefinisikan ulang warna melalui gaya sebaris. Ini bisa menjadi opsi, tetapi kemungkinan besar pendekatan ini akan kurang optimal karena Anda harus memiliki akses ke elemen tertentu dan mengubah properti warnanya. Dengan variabel CSS, Anda hanya akan mengubah satu properti, yaitu nilai variabel.
Dalam JavaScript, tidak ada fungsi asli atau API untuk bekerja dengan warna. Dalam Modul Warna CSS 5, akan ada banyak peluang untuk membuat warna turunan atau menghitungnya. Dari perspektif masa depan, Properti Kustom CSS lebih kaya dan lebih fleksibel daripada variabel JS. Juga, dengan variabel JS, tidak akan ada kemungkinan untuk menggunakan pewarisan dalam kaskade dan itulah kelemahan utamanya.
Kesimpulan
Memisahkan warna menjadi tiga level (palet, fungsional, dan komponen) dapat membantu Anda lebih adaptif terhadap perubahan dan persyaratan baru saat mengerjakan proyek. Saya percaya bahwa CSS Custom Properties adalah alat yang tepat untuk mengatur pemisahan warna — tidak masalah apa yang Anda gunakan untuk penataan: CSS murni, praprosesor, atau pendekatan CSS-in-JS.
Saya sampai pada pendekatan ini melalui pengalaman saya sendiri, tetapi saya tidak sendirian. Sara Soueidan menjelaskan dalam artikelnya pendekatan serupa di mana dia membagi variabel menjadi tingkat global dan komponen.
Saya juga ingin menyarankan membaca artikel Lea Verou di mana dia menjelaskan kemungkinan kasus penerapan variabel CSS (tidak hanya dalam hal warna).