Membuat skema warna

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.

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.

pratinjau hasil akhir tema terang

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;
}
screenshot warna terang secara bersamaan
Sandbox di CodePen

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:

  1. Pengguna biasanya akan berada dalam gelap saat menggunakan tema ini, jadi uji di tempat gelap.
  2. Warna harus didesaturasi agar tidak bergetar di layar karena terlalu intens.

pratinjau hasil akhir tema gelap

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;
}
screenshot warna gelap secara bersamaan
Sandbox di CodePen

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.

pratinjau hasil akhir dari tema redup

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;
}
screenshot warna redup secara bersamaan
Sandbox di CodePen

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.

shift + panah bawah ditekan untuk menurunkan kecerahan dan meningkatkan kontras hingga melewati

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);
}
Screenshot permukaan redup dan pasangan teks
Screenshot permukaan redup dan pasangan teks dengan VisBug

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.

setiap bayangan berdampingan satu sama lain

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.