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 menonton video, berikut versi YouTube untuk postingan ini:

Ringkasan

Kita akan membangun sistem warna yang dapat diakses dengan properti kustom dan calc(), untuk membuat halaman web yang adaptif terhadap preferensi pengguna dengan tetap mempertahankan minim pengalaman. 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 depan. Tidak sampai bagian akhir, mereka terbiasa mengubah halaman.

Merek

Sering kali, warna merek telah ditetapkan dan dikirimkan 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 memungkinkan konsep penggelapan atau pencerahan warna merek, misalnya 20%, 3 saluran nilai warna hsl harus diekstrak ke dalam kustomnya sendiri properti tersebut, 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 yang cocok, dalam hal ini, masing-masing ditambahkan dengan -light.

pratinjau hasil akhir tema terang

Merek

Dimulai dengan warna merek, warna ini 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 akan sangat gelap. Perhatikan bagaimana {i>lightness<i} warna-warna berikut ini rendah, di bawah 50%.

* {
  --text1-light: hsl(var(--brand-hue) var(--brand-saturation) 10%);
  --text2-light: hsl(var(--brand-hue) 30% 30%);
}

--text1-light, karena gelap sekali dengan kecerahan 10%, kecerahannya tetap 100% saturasi sehingga warna merek masih bisa masuk ke warna biru tua gelap.

--text2-light, warnanya tidak gelap seperti warna pertama, yang bagus karena warna sekunder, dan juga tidak terlalu tersaturasi.

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, seperti dibandingkan 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 muda 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 (kecerahan 99% hingga kecerahan 92%; membuatnya lebih gelap).

Bayangan

Bayangan dalam skema warna memiliki efek yang sangat besar, tetapi menambahkan nuansa hidup di efek dan membantu menonjolkannya dari bayangan 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 sedikit 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 membutuhkan bagian-bagian kecil tersebut untuk melakukan kalkulasi. Langsung ke bayangan rad untuk mempelajari lebih lanjut.

Warna-warna terang menyatu

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, tema yang biasanya lebih ringan. Di sisi lain, pengguna sering kali memilih tema gelap untuk konteks yang berbeda, seperti malam hari. Faktor-faktor ini mendorong saya untuk menyimpan dua hal-hal dengan tema gelap:

  1. Pengguna biasanya akan berada dalam gelap saat menggunakan tema ini, jadi uji di gelap.
  2. Warna harus berkurang saturasinya 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 berkurang menjadi dua dan kecerahan dikurangi relatif 50%.

* {
  --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 kecerahan, membuatnya lebih dekat ke putih.

* {
  --text1-dark: hsl(var(--brand-hue) 15% 85%);
  --text2-dark: hsl(var(--brand-hue) 5% 65%);
}

Warna permukaan

Dalam tema gelap, warna permukaan harus gelap. Warna berikut memiliki cahaya dan saturasi rendah, dengan permukaan pertama adalah yang paling gelap sebesar 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 besar saturasi yang ada dalam bayangan itu. 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;
}

Redupkan 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 keseluruhan
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%. Itu berarti 40% kecerahan ruang bernapas di antara mereka. Dalam tema terang, ada 55% ruang pernapasan di tema terang. Mempertahankan perbedaan kecerahan antara warna teks dan permukaan sekitar 40-50% dapat membantu menjaga rasio kontras warna tetap tinggi, sekaligus tuas kecil untuk menyesuaikan jika skor rendah.

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 sampai 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 penyandingan teks
Screenshot permukaan redup dan penyambungan teks dengan VisBug

Bayangan Cerah

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 bisa saya sesuaikan dalam setiap skema warna.

setiap bayangan berdampingan satu sama lain

Untuk mencapai ini, saya membuat 2 variabel untuk setiap skema warna untuk disesuaikan, warna bayangan dan kekuatan bayangan. Warnanya digunakan untuk saturasi dan kegelapan penyesuaian, sedangkan kekuatannya adalah cara mudah untuk meningkatkan bayangan intensitas warna saat itu adalah 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 saya melangkah lebih jauh dengan menggunakan bayangan dalam skema warna, saya akan membuat konstanta token desain juga, 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 CSS di dalam proyek skema warna ini, kita tidak perlu sering mengakses nilai skema warna tertentu. Saya ingin membuatnya mudah untuk tetap berada dalam 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.

Lebih mendalam, 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 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

Sekarang setelah Anda tahu cara saya melakukannya, bagaimana Anda akan 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.