Membuat skema warna

Ringkasan dasar tentang cara membuat skema warna yang dinamis dan dapat dikonfigurasi

Dalam postingan ini, saya ingin membagikan pemikiran tentang cara mengelola beberapa skema warna di CSS. Coba demo.

Demo

Jika Anda lebih suka menonton video, berikut versi YouTube untuk 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 dari itu: 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.

Merek

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 {i>hex<i} perlu dikonversi menjadi 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 fondasi untuk membangun skema warna karena CSS dapat mempertahankan semua warna dalam kelompok hue yang sama dengan menyesuaikan tingkat 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, dibuat ulang dengan menggabungkan --brand-hue, --brand-saturation dan --brand-lightness di dalam tanda kurung fungsi () hsl, tanpa kalkulasi apa pun:

* {
  --brand-light: hsl(var(--brand-hue) var(--brand-saturation) var(--brand-lightness));
}

Warna teks

Selanjutnya, hal-hal penting dari skema warna membutuhkan 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, warna ini tidak terlalu gelap seperti warna pertama, yang bagus karena merupakan warna sekunder, dan juga jauh lebih tidak jenuh.

Warna permukaan

Warna permukaan adalah latar belakang, batas, dan permukaan dekoratif lainnya yang teks yang berada di atas atau di dalamnya. 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 permukaan diciptakan karena warna dekoratif cenderung membutuhkan lebih banyak varian, untuk momen interaktif seperti :focus atau :hover atau untuk membuat tampilan lapisan kertas. Dalam skenario ini, sangat baik untuk mengubah --surface2-light saat mengarahkan kursor ke --surface3-light, sehingga pengarahan kursor akan menghasilkan peningkatan kontras (99% kecerahan hingga 92% kecerahan; membuatnya lebih gelap).

Bayangan

Bayangan dalam skema warna sangat penting, tetapi tambahkan nuansa alami yang hidup ke efek dan bantu agar terlihat berbeda dari bayangan berbasis hitam yang tidak realistis. Yang akan dilakukan ini, warna bayangan akan menggunakan properti khusus hue, menjadi sedikit jenuh dengan rona warna tapi masih sangat gelap. Pada dasarnya, membangun situasi yang sangat gelap bayangan yang agak 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 bayangan rad untuk mempelajari lebih lanjut.

Warna terang semuanya

Tidak perlu mencari-cari untuk mengetahui bagaimana warna-warna terang dibuat, semuanya 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 merek tidak dimulai dengan tema gelap, tapi ini varian dari tema utama, yang biasanya lebih ringan. Di sisi lain, pengguna sering kali memilih tema gelap untuk konteks yang berbeda, seperti malam hari. Faktor-faktor ini telah membuat saya mengingat dua hal dengan tema gelap:

  1. Pengguna biasanya akan berada dalam kegelapan saat menggunakan tema ini, jadi uji dalam kegelapan.
  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 bisa dilihat. 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-warna berikut memiliki nilai kecerahan, mendekatkannya ke warna 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. Hal ini masuk akal karena sulit membuat sesuatu yang sudah cukup gelap menjadi lebih 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 warnanya ketika Anda melihat antarmukanya? Coba hapus saturasi dari devtools, mana yang kamu mau?!

Semua warna gelap

* {
  --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 adalah tentang orkestrasi kecerahan dan saturasi. Ada harus ada saturasi yang cukup untuk tetap memiliki hue, tetapi juga harus hampir tidak lulus skor kontras karena dimaksudkan agar 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 aksesibel

Perhatikan bagaimana kecerahan terendah dalam set warna teks gelap adalah 65% dan cahaya paling rendah di permukaan gelap adalah 25%. Artinya, ada ruang gerak 40% 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 nilai kecerahan sampai 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 kontras yang baik, sebaiknya buat class name yang memasangkan warna platform 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 penyambungan teks dengan VisBug

Rad Shadow

Tema menggunakan class utilitas yang disebut .rad-shadow. Bayangan ini dibuat alat Smooth Shadow ini, yang sangat saya hargai banyak. Saya mengambil cuplikan yang dihasilkannya dan menyesuaikannya dengan warna saya sendiri dan, dan opasitas. 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 setiap skema warna yang akan disesuaikan, yaitu 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 kurang lebih 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 menentukan warna yang lengkap, 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 khusus generik, yang akan kita tentukan sebentar lagi. Dengan begini, orang yang menggunakan variabel desain tidak perlu khawatir tentang skema warna mana saat ini disetel, mereka hanya perlu menggunakan warna permukaan dan teks. Daripada fokus pada color: var(--text1-light) menggunakan color: var(--text1). Semua kemampuan beradaptasi dan perubahan warna dilakukan di tingkat yang lebih tinggi di CSS.

Gaya penghubung tema terang dalam blok kode berikut, menghubungkan properti kustom generik dengan warna khusus 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 sekarang menggunakan tema terang. Ini adalah momen sukses yang sangat menyenangkan. Mari kita nikmati beberapa momen tersebut saat kita menggunakan warna yang telah ditentukan sebelumnya di konteks skema warna.

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 titik ini, penulis bebas menggunakan skema warna generik yang disediakan dibutuhkan, dan tidak perlu mengkhawatirkan tema lagi.

Kesimpulan

Setelah Anda tahu cara saya melakukannya, bagaimana Anda melakukannya? 🙂

Mari kita diversifikasi pendekatan kami dan mempelajari semua cara untuk membangun di web. Buat Codepen atau host demo Anda sendiri, kirim tweet kepada saya, dan saya akan menambahkannya ke Bagian remix komunitas di bawah ini.

Sumber

Remix komunitas - @chris-kruining menambahkan penggeser hue. warna status dan mode kontras untuk no-preference, more, dan less: demo.