Ringkasan dasar tentang cara membuat skema warna yang dinamis dan dapat dikonfigurasi
Dalam postingan ini, saya ingin berbagi pemikiran tentang cara mengelola beberapa skema warna di CSS. Coba demo.
Jika Anda lebih suka video, berikut versi YouTube dari postingan ini:
Ringkasan
Kita akan membuat sistem warna yang mudah diakses dengan properti kustom dan calc()
, untuk
membuat halaman web yang adaptif terhadap preferensi pengguna sekaligus menjaga pengalaman
penulisan tetap minimal. Kami mulai dengan warna merek dasar dan membangun sistem
varian darinya: 2 warna teks, 4 warna permukaan, dan bayangan yang cocok.
Panduan ini dimulai dengan menentukan semua warna untuk setiap skema warna terlebih dahulu. Hanya di bagian akhir, tombol ini digunakan untuk mengubah halaman.
Brand
Sering kali, warna merek telah ditetapkan dan dikirim sebagai
hex atau
rgb. Tantangan GUI ini
memiliki warna merek dasar #0af
. Pertama, untuk sistem warna ini, nilai heksadesimal
perlu dikonversi ke
hsl.
* {
--brand: #0af;
--brand: hsl(200 100% 50%);
}
Untuk mengaktifkan konsep penggelapan atau pencerahan warna merek, misalnya 20%, 3 saluran nilai warna hsl perlu diekstrak ke dalam properti kustomnya sendiri, seperti ini:
* {
--brand-hue: 200;
--brand-saturation: 100%;
--brand-lightness: 50%;
}
CSS dapat melakukan perhitungan pada properti warna tersebut, misalnya calc(var(--brand-lightness) -
20%)
untuk mengurangi nilai kecerahan sebesar 20%. Hal ini merupakan dasar untuk membangun
skema warna karena CSS dapat menyimpan semua warna dalam kelompok hue yang sama dengan menyesuaikan
jumlah saturasi dan kecerahan hsl.
Tema terang
Setiap varian warna akan ditandai dengan skema pencocokannya, dalam hal ini, setiap varian
akan ditambahkan dengan -light
.
Merek
Dimulai dengan warna merek, warna tersebut akan dibuat ulang dengan menggabungkan properti kustom --brand-hue
, --brand-saturation
,
dan --brand-lightness
di dalam tanda kurung fungsi hsl ()
,
tanpa penghitungan apa pun:
* {
--brand-light: hsl(var(--brand-hue) var(--brand-saturation) var(--brand-lightness));
}
Warna teks
Selanjutnya, elemen penting skema warna memerlukan warna teks. Dalam tema terang, teks harus sangat gelap. Perhatikan bahwa kecerahan warna berikut rendah, jauh di bawah 50%.
* {
--text1-light: hsl(var(--brand-hue) var(--brand-saturation) 10%);
--text2-light: hsl(var(--brand-hue) 30% 30%);
}
--text1-light
, karena sangat gelap dengan kecerahan 10%, mempertahankan saturasi 100%
yang berat sehingga warna merek masih dapat terlihat melalui warna navy gelap.
--text2-light
, warnanya tidak gelap seperti warna pertama, yang bagus karena merupakan
warna sekunder, dan juga tidak terlalu gelap.
Warna permukaan
Warna platform adalah latar belakang, batas, dan platform dekoratif lainnya yang menjadi tempat teks. Dalam tema terang, ini adalah warna terang, sebaliknya dengan warna teks yang gelap. Untuk membuat warna terang dengan hsl, kita akan menggunakan nilai persentase yang lebih tinggi dalam nilai kecerahan ketiga. Kita juga akan menurunkan saturasi, sehingga abu-abu terang tidak terlihat terlalu berwarna.
* {
--surface1-light: hsl(var(--brand-hue) 25% 90%);
--surface2-light: hsl(var(--brand-hue) 20% 99%);
--surface3-light: hsl(var(--brand-hue) 20% 92%);
--surface4-light: hsl(var(--brand-hue) 20% 85%);
}
4 warna platform dibuat karena warna dekoratif cenderung memerlukan lebih banyak
varian, untuk momen interaktif seperti :focus
atau :hover
atau untuk membuat
tampilan lapisan kertas. Dalam skenario ini, sebaiknya transisikan
--surface2-light
saat mengarahkan kursor ke --surface3-light
, sehingga mengarahkan kursor akan menghasilkan
peningkatan kontras (kecerahan 99% menjadi kecerahan 92%; membuatnya lebih gelap).
Bayangan
Bayangan dalam skema warna memiliki kelebihan dan kekurangan, tetapi menambahkan kesan realistis pada efek dan membuatnya tampil beda dari bayangan berbasis hitam yang tidak realistis. Untuk melakukannya, warna bayangan akan menggunakan properti kustom hue, sedikit tepu dengan hue, tetapi masih sangat gelap. Pada dasarnya membuat bayangan yang sangat gelap dan sedikit berwarna biru.
* {
--surface-shadow-light: var(--brand-hue) 10% 20%;
--shadow-strength-light: .02;
}
--surface-shadow-light
tidak digabungkan dalam fungsi hsl. Hal ini karena
nilai --shadow-strength
akan digabungkan untuk membuat beberapa opasitas, dan CSS memerlukan
bagian-bagian tersebut untuk melakukan penghitungan. Langsung ke bagian bayangan
rad untuk mempelajari lebih lanjut.
Warna terang semuanya
Tidak perlu mencari-cari untuk menemukan cara pembuatan warna terang, semuanya ada di satu tempat di CSS.
* {
--brand-light: hsl(var(--brand-hue) var(--brand-saturation) var(--brand-lightness));
--text1-light: hsl(var(--brand-hue) var(--brand-saturation) 10%);
--text2-light: hsl(var(--brand-hue) 30% 30%);
--surface1-light: hsl(var(--brand-hue) 25% 90%);
--surface2-light: hsl(var(--brand-hue) 20% 99%);
--surface3-light: hsl(var(--brand-hue) 20% 92%);
--surface4-light: hsl(var(--brand-hue) 20% 85%);
--surface-shadow-light: var(--brand-hue) 10% calc(var(--brand-lightness) / 5);
--shadow-strength-light: .02;
}
Tema gelap
Sebagian besar brand tidak memulai dengan tema gelap, melainkan varian dari tema utama mereka, yang biasanya lebih terang. Di sisi lain, pengguna sering kali memilih tema gelap untuk konteks yang berbeda, seperti waktu malam. Faktor-faktor ini telah membuat saya mengingat dua hal dengan tema gelap:
- Pengguna biasanya akan berada dalam gelap saat menggunakan tema ini, jadi uji di tempat gelap.
- Warna harus didesaturasi agar tidak bergetar di layar karena terlalu intens.
Merek
Tema terang menggunakan 3 nilai saluran warna hsl merek tanpa perubahan, tema gelap tidak. Saturasi dipotong setengah dan kecerahan dikurangi sebesar 50% relatif.
* {
--brand-dark: hsl(
var(--brand-hue)
calc(var(--brand-saturation) / 2)
calc(var(--brand-lightness) / 1.5)
);
}
Warna teks
Dalam tema gelap, warna teks harus terang. Warna berikut memiliki nilai terang yang tinggi, sehingga lebih mendekati putih.
* {
--text1-dark: hsl(var(--brand-hue) 15% 85%);
--text2-dark: hsl(var(--brand-hue) 5% 65%);
}
Warna permukaan
Dalam tema gelap, warna platform harus gelap. Warna berikut memiliki kecerahan dan saturasi rendah, dengan permukaan pertama menjadi yang paling gelap pada 10%.
* {
--surface1-dark: hsl(var(--brand-hue) 10% 10%);
--surface2-dark: hsl(var(--brand-hue) 10% 15%);
--surface3-dark: hsl(var(--brand-hue) 5% 20%);
--surface4-dark: hsl(var(--brand-hue) 5% 25%);
}
Bayangan
Dalam tema gelap, bayangan bisa sangat sulit dilihat. Masuk akal karena sulit untuk menggelapkan
sesuatu yang sudah cukup gelap. Di sinilah
--shadow-strength-dark
sangat berguna karena memungkinkan kita menggelapkan
bayangan dengan mengubah satu variabel.
* {
--surface-shadow-dark: var(--brand-hue) 50% 3%;
--shadow-strength-dark: .8;
}
Selain itu, lihat seberapa banyak saturasi dalam bayangan tersebut. Dapatkah Anda melihat warna saat melihat antarmuka? Coba hapus saturasi dari devtools, mana yang Anda sukai?
Warna gelap secara bersamaan
* {
--brand-dark: hsl(var(--brand-hue) calc(var(--brand-saturation) / 2) calc(var(--brand-lightness) / 1.5));
--text1-dark: hsl(var(--brand-hue) 15% 85%);
--text2-dark: hsl(var(--brand-hue) 5% 65%);
--surface1-dark: hsl(var(--brand-hue) 10% 10%);
--surface2-dark: hsl(var(--brand-hue) 10% 15%);
--surface3-dark: hsl(var(--brand-hue) 5% 20%);
--surface4-dark: hsl(var(--brand-hue) 5% 25%);
--surface-shadow-dark: var(--brand-hue) 50% 3%;
--shadow-strength-dark: .8;
}
Tema redup
Skema warna ini berfokus pada pengaturan kecerahan dan saturasi. Harus ada saturasi yang cukup agar warna masih terlihat, tetapi juga harus hampir lulus skor kontras karena warnanya dimaksudkan untuk redup dan kontras rendah.
Merek
* {
--brand-dim: hsl(
var(--brand-hue)
calc(var(--brand-saturation) / 1.25)
calc(var(--brand-lightness) / 1.25)
);
}
Warna teks
* {
--text1-dim: hsl(var(--brand-hue) 15% 75%);
--text2-dim: hsl(var(--brand-hue) 10% 61%);
}
Warna permukaan
* {
--surface1-dim: hsl(var(--brand-hue) 10% 20%);
--surface2-dim: hsl(var(--brand-hue) 10% 25%);
--surface3-dim: hsl(var(--brand-hue) 5% 30%);
--surface4-dim: hsl(var(--brand-hue) 5% 35%);
}
Bayangan
* {
--surface-shadow-dim: var(--brand-hue) 30% 13%;
--shadow-strength-dim: .2;
}
Meredupkan semua warna
* {
--brand-dim: hsl(var(--brand-hue) calc(var(--brand-saturation) / 1.25) calc(var(--brand-lightness) / 1.25));
--text1-dim: hsl(var(--brand-hue) 15% 75%);
--text2-dim: hsl(var(--brand-hue) 10% 61%);
--surface1-dim: hsl(var(--brand-hue) 10% 20%);
--surface2-dim: hsl(var(--brand-hue) 10% 25%);
--surface3-dim: hsl(var(--brand-hue) 5% 30%);
--surface4-dim: hsl(var(--brand-hue) 5% 35%);
--surface-shadow-dim: var(--brand-hue) 30% 13%;
--shadow-strength-dim: .2;
}
Warna yang mudah diakses
Perhatikan bahwa kecerahan terendah dalam kumpulan warna teks gelap adalah 65% dan kecerahan tertinggi di permukaan gelap adalah 25%. Artinya, ada ruang 40% yang lebih terang di antara keduanya. Dalam tema terang, ada ruang 55% untuk bernapas dalam tema terang. Menjaga perbedaan kecerahan antara warna teks dan permukaan di sekitar 40-50% dapat membantu menjaga rasio kontras warna tetap tinggi, sekaligus menjadi tombol halus untuk disesuaikan jika skornya buruk.
Saya menyebutnya "bump bump til ya pass", yang merupakan interaksi dari peningkatan nilai kecerahan hingga alat menunjukkan bahwa saya lulus.
Setiap tema yang dibuat dalam tantangan ini lulus skor kontras. Skema warna redup memiliki kontras terendah, tetapi masih memenuhi persyaratan minimum. Untuk membantu orang lain dalam tim menggunakan warna-warna kontras yang bagus, sebaiknya buat nama kelas yang memadukan warna permukaan dengan warna teks yang mudah diakses.
.surface1 {
background-color: var(--surface1);
color: var(--text2);
}
.surface2 {
background-color: var(--surface2);
color: var(--text2);
}
.surface3 {
background-color: var(--surface3);
color: var(--text1);
}
.surface4 {
background-color: var(--surface4);
color: var(--text1);
}
Rad Shadow
Tema menggunakan class utilitas yang disebut .rad-shadow
. Bayangan ini dihasilkan
di alat Smooth Shadow ini, yang sangat saya
hargai. Saya mengambil cuplikan yang dihasilkan dan menyesuaikannya dengan warna dan
penghitungan opasitas saya sendiri. Alasannya adalah untuk membuat bayangan yang dapat saya sesuaikan
dalam setiap skema warna.
Untuk melakukannya, saya membuat 2 variabel untuk disesuaikan oleh setiap skema warna, warna bayangan dan kekuatan bayangan. Warna digunakan untuk penyesuaian saturasi dan gelap, sedangkan kekuatan digunakan untuk cara mudah meningkatkan intensitas bayangan jika menggunakan skema warna gelap. Hasil akhirnya akan terlihat seperti ini.
:root {
--surface-shadow-light: var(--brand-hue) 10% 20%;
--shadow-strength-light: .02;
}
.rad-shadow {
box-shadow:
0 2.8px 2.2px hsl(var(--surface-shadow) / calc(var(--shadow-strength) + .03)),
0 6.7px 5.3px hsl(var(--surface-shadow) / calc(var(--shadow-strength) + .01)),
0 12.5px 10px hsl(var(--surface-shadow) / calc(var(--shadow-strength) + .02)),
0 22.3px 17.9px hsl(var(--surface-shadow) / calc(var(--shadow-strength) + .02)),
0 41.8px 33.4px hsl(var(--surface-shadow) / calc(var(--shadow-strength) + .03)),
0 100px 80px hsl(var(--surface-shadow) / var(--shadow-strength))
;
}
Jika ingin lebih jauh dengan bayangan dalam skema warna, saya juga akan membuat sudut bayangan menjadi konstanta token desain, karena arah cahaya harus sama di antara semua bayangan desain.
Penggunaan skema warna
Setelah penetapan warna selesai, saatnya untuk mengubahnya menjadi properti agnostik skema. Yang saya maksud adalah, sebagai penulis CSS di dalam project skema warna ini, Anda jarang perlu mengakses nilai skema warna tertentu. Saya ingin memudahkan Anda untuk tetap menggunakan tema.
Untuk mencapai hal ini, penggunaan skema warna harus dilakukan secara eksklusif melalui
properti kustom generik, yang akan kita tentukan sebentar lagi. Dengan cara ini,
orang yang menggunakan variabel desain tidak perlu khawatir dengan skema warna
yang saat ini ditetapkan, mereka hanya perlu menggunakan warna permukaan dan teks. Sebagai ganti
color: var(--text1-light)
, gunakan color: var(--text1)
. Semua penyesuaian dan perputaran
warna dilakukan pada tingkat yang jauh lebih tinggi di CSS.
Selanjutnya, gaya penghubung tema terang dalam blok kode berikut,
hubungkan properti kustom generik dengan warna spesifik tema terang. Sekarang semua
penggunaan var(--brand)
akan menggunakan warna merek terang.
Tema terang (otomatis)
:root {
color-scheme: light;
--brand: var(--brand-light);
--text1: var(--text1-light);
--text2: var(--text2-light);
--surface1: var(--surface1-light);
--surface2: var(--surface2-light);
--surface3: var(--surface3-light);
--surface4: var(--surface4-light);
--surface-shadow: var(--surface-shadow-light);
--shadow-strength: var(--shadow-strength-light);
}
Situs kini menggunakan tema terang. Ini adalah momen sukses yang sangat menyenangkan. Mari kita nikmati beberapa momen tersebut saat kita menggunakan warna yang telah ditentukan sebelumnya dalam konteks skema warna lainnya.
Tema gelap (otomatis)
@media (prefers-color-scheme: dark) {
:root {
color-scheme: dark;
--brand: var(--brand-dark);
--text1: var(--text1-dark);
--text2: var(--text2-dark);
--surface1: var(--surface1-dark);
--surface2: var(--surface2-dark);
--surface3: var(--surface3-dark);
--surface4: var(--surface4-dark);
--surface-shadow: var(--surface-shadow-dark);
--shadow-strength: var(--shadow-strength-dark);
}
}
Tema terang
[color-scheme="light"] {
color-scheme: light;
--brand: var(--brand-light);
--text1: var(--text1-light);
--text2: var(--text2-light);
--surface1: var(--surface1-light);
--surface2: var(--surface2-light);
--surface3: var(--surface3-light);
--surface4: var(--surface4-light);
--surface-shadow: var(--surface-shadow-light);
--shadow-strength: var(--shadow-strength-light);
}
Tema gelap
[color-scheme="dark"] {
color-scheme: dark;
--brand: var(--brand-dark);
--text1: var(--text1-dark);
--text2: var(--text2-dark);
--surface1: var(--surface1-dark);
--surface2: var(--surface2-dark);
--surface3: var(--surface3-dark);
--surface4: var(--surface4-dark);
--surface-shadow: var(--surface-shadow-dark);
--shadow-strength: var(--shadow-strength-dark);
}
Tema redup
[color-scheme="dim"] {
color-scheme: dark;
--brand: var(--brand-dim);
--text1: var(--text1-dim);
--text2: var(--text2-dim);
--surface1: var(--surface1-dim);
--surface2: var(--surface2-dim);
--surface3: var(--surface3-dim);
--surface4: var(--surface4-dim);
--surface-shadow: var(--surface-shadow-dim);
--shadow-strength: var(--shadow-strength-dim);
}
Pada tahap ini, penulis bebas menggunakan generik skema warna yang disediakan sesuai kebutuhan, dan tidak perlu lagi khawatir tentang tema.
Kesimpulan
Setelah Anda tahu cara saya melakukannya, bagaimana Anda melakukannya? 🙂
Mari kita diversifikasi pendekatan dan pelajari semua cara untuk mem-build di web. Buat Codepen atau host demo Anda sendiri, tweet ke saya, dan saya akan menambahkannya ke bagian Remix komunitas di bawah.
Sumber
Remix komunitas
- @chris-kruining menambahkan penggeser hue,
warna status, dan mode kontras untuk no-preference
, more
, dan less
:
demo.