Membuat skema warna

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

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

Demo

Jika Anda lebih suka video, berikut versi YouTube postingan ini:

Ringkasan

Kita akan membangun sistem warna yang dapat diakses dengan properti khusus dan calc(), untuk membuat halaman web yang adaptif dengan preferensi pengguna sekaligus meminimalkan pengalaman penulisan. Kita mulai dengan warna merek dasar dan mem-build sistem varian darinya: 2 warna teks, 4 warna platform, dan bayangan yang cocok.

Panduan ini dimulai dengan menentukan semua warna untuk setiap skema warna sejak awal. Tidak sampai akhir, mereka digunakan untuk 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 heksadesimal perlu dikonversi menjadi hsl.

* {
  --brand: #0af;
  --brand: hsl(200 100% 50%);
}

Untuk mengaktifkan konsep penggelapan atau pencerahan warna merek, misalnya 20%, 3 saluran dari nilai warna hsl perlu diekstrak ke 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 sangat mendasar dalam 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 yang cocok. Dalam hal ini, setiap varian ditambahkan dengan -light.

pratinjau hasil akhir tema terang

Merek

Dimulai dengan warna merek, kode ini dibuat ulang dengan menggabungkan properti khusus --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, hal-hal penting dari skema warna membutuhkan warna teks. Dalam tema terang, teks harus sangat gelap. Perhatikan bahwa kecerahan warna berikut 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 sangat gelap dengan kecerahan 10%, mempertahankan saturasi yang 100% berat sehingga warna merek masih dapat mengintip ke dalam biru gelap yang gelap.

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

Warna permukaan

Warna permukaan adalah latar belakang, batas, dan permukaan dekoratif lainnya tempat teks berada di dalam atau di dalamnya. Dalam tema terang, ini adalah warna terang, berbeda dengan warna teks yang gelap. Untuk membuat warna terang dengan hsl, kita gunakan nilai persentase yang lebih tinggi pada nilai kecerahan ketiga. Kita juga akan menurunkan saturasi, sehingga warna 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 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 pengarahan kursor menghasilkan peningkatan kontras (99% kecerahan menjadi 92% kecerahan; menjadikannya lebih gelap).

Bayangan

Bayangan dalam skema warna melebihi batas, tetapi menambahkan sifat yang realistis pada efek dan membantunya menonjol dari bayangan berbasis hitam yang tidak realistis. Untuk melakukannya, warna bayangan akan menggunakan properti kustom hue, sedikit tersaturasi dengan hue, tetapi masih sangat gelap. Pada dasarnya, membangun 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 menciptakan opasitas, dan CSS memerlukan potongan tersebut untuk melakukan penghitungan. Langsung ke bagian bayangan rad untuk mempelajari lebih lanjut.

Memenuhi semua warna terang

Anda tidak perlu mencari-cari untuk mencari tahu bagaimana warna-warna terang tersebut tercipta, semuanya berada 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-warna terang sekaligus
Sandbox di CodePen

Tema gelap

Sebagian besar merek tidak memulai dengan tema gelap, ini adalah varian dari tema utama, biasanya lebih terang, Di sisi lain, pengguna sering memilih tema gelap untuk konteks yang berbeda, seperti malam hari. Faktor-faktor ini membuat saya mengingat dua hal dengan tema gelap:

  1. Pengguna umumnya akan berada dalam gelap saat menggunakan tema ini, jadi uji dalam gelap.
  2. Warna akan menurun saturasinya agar tidak bergetar di layar karena menjadi terlalu intens.

pratinjau hasil akhir tema gelap

Merek

Tema terang menggunakan 3 nilai saluran warna hsl merek tanpa perubahan, sedangkan tema gelap tidak. Saturasi terpotong menjadi dua dan kecerahan berkurang relatif 50%.

* {
  --brand-dark: hsl(
    var(--brand-hue)
    calc(var(--brand-saturation) / 2)
    calc(var(--brand-lightness) / 1.5)
  );
}

Warna teks

Di tema gelap, warna teks harus terang. Warna berikut memiliki nilai tinggi untuk kecerahan, yang menempatkannya 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 platform harus gelap. Warna berikut memiliki cahaya dan saturasi yang rendah, dengan permukaan pertama menjadi 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 akan sangat sulit dilihat. Masuk akal karena sulit untuk menggelapkan sesuatu yang sudah cukup gelap. Di sinilah --shadow-strength-dark sangat berguna karena memungkinkan kita untuk 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 ketika Anda melihat antarmukanya? Coba hapus saturasi dari devtools, mana yang Anda suka?!

Menggunakan warna-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 bertujuan untuk mengatur kecerahan dan saturasi. hue harus ada cukup saturasi agar hue tetap terlihat, tetapi juga hampir tidak lulus skor kontras karena hue ini dimaksudkan untuk tetap redup dan kontrasnya 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 bersama-sama
Sandbox di CodePen

Warna yang aksesibel

Perhatikan bagaimana kecerahan terendah dalam set warna teks gelap adalah 65% dan kecerahan tertinggi di permukaan gelap adalah 25%. Ada 40% cahaya yang sepotong ruang di antara mereka. Pada tema terang, ada 55% ruang pernapasan pada tema terang. Mempertahankan perbedaan kecerahan antara warna teks dan permukaan sekitar 40-50% dapat membantu menjaga rasio kontras warna tetap tinggi, sekaligus juga menjadi tuas yang halus untuk disesuaikan jika skor buruk.

Saya menyebutnya "bump bump til ya pass", yang merupakan interaksi dari penambahan nilai kecerahan hingga alat menunjukkan bahwa saya berhasil.

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

Setiap tema yang dibuat dalam tantangan ini lulus skor kontras. Skema warna redup memiliki kontras terendah, tetapi masih memenuhi persyaratan minimum. Untuk membantu anggota tim lainnya menggunakan warna kontras yang baik, sebaiknya buat nama class yang memasangkan warna permukaan dengan warna teks yang dapat 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 yang redup dan penyambungan teks dengan VisBug

Bayangan Rad

Tema menggunakan class utilitas yang disebut .rad-shadow. Bayangan ini dihasilkan pada alat Smooth Shadow ini, yang sangat saya hargai. Saya mengambil cuplikan yang dihasilkannya dan menyesuaikannya dengan warna dan, kalkulasi opasitas saya sendiri. Alasannya adalah untuk membuat bayangan yang bisa saya sesuaikan dalam setiap skema warna.

setiap bayangan bersebelahan satu sama lain

Untuk melakukannya, saya membuat 2 variabel untuk disesuaikan setiap skema warna, warna bayangan dan kekuatan bayangan. Warna ini untuk penyesuaian saturasi dan kegelapan, sedangkan kekuatannya adalah cara mudah untuk 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 menggunakan bayangan dalam skema warna, saya juga harus membuat sudut bayangan menjadi konstanta token desain, karena arah cahaya harus sama di antara semua bayangan desain.

Menggunakan skema warna

Setelah penentuan warna selesai, saatnya untuk mengubahnya menjadi properti agnostik skema. Maksud saya adalah, sebagai penulis CSS dalam project skema warna ini, orang seharusnya jarang mengakses nilai skema warna tertentu. Saya ingin membuatnya mudah untuk tetap sesuai dengan tema.

Untuk melakukannya, penggunaan skema warna harus dilakukan secara eksklusif melalui properti kustom umum, yang akan kita tentukan sebentar lagi. Dengan cara ini, orang yang menggunakan variabel desain tidak perlu khawatir tentang skema warna mana yang saat ini ditetapkan, mereka hanya perlu menggunakan warna permukaan dan teks. Sebagai ganti color: var(--text1-light), gunakan color: var(--text1). Semua adaptasi dan perubahan warna dilakukan dengan cara yang jauh lebih tinggi di CSS.

Dengan mempelajari lebih dalam, gaya penghubung tema terang di blok kode berikut, hubungkan 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 kini menggunakan tema terang. Ini adalah momen sukses yang sangat menyenangkan. Mari kita lihat beberapa momen seperti itu saat kita menggunakan warna yang telah ditentukan dalam konteks skema warna lain.

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 mengkhawatirkan tema lagi.

Kesimpulan

Sekarang Anda tahu bagaimana saya melakukannya, bagaimana Anda akan?! 🙂

Mari lakukan diversifikasi pendekatan dan pelajari semua cara untuk membangun di web. Buat Codepen atau host demo Anda sendiri, kirim tweet, 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.