Sintaksis warna relatif CSS

Buat warna baru berdasarkan saluran dan nilai warna lain.

Adam Argyle
Adam Argyle

Di Chrome 119, terdapat fitur warna yang sangat canggih dari CSS Color Level 5. Sintaksis warna relatif membuat jalur mulus untuk manipulasi warna dalam CSS, yang menawarkan cara bagi penulis dan desainer untuk:

Sebelum sintaksis warna relatif, untuk mengubah opasitas warna, Anda harus membuat properti khusus untuk saluran warna, biasanya HSL, dan menyusunnya menjadi warna akhir dan warna varian akhir. Ini berarti mengelola banyak bagian warna, yang bisa dengan cepat menjadi membebani.

:root {
  --brand-hue: 300deg;
  --brand-saturation: 75%;
  --brand-lightness: 50%;

  --brand-hsl:
    var(--brand-hue)
    var(--brand-saturation)
    var(--brand-lightness);

  --brand-color: hsl(var(--brand-hsl));

  /* all this work just so I can set the opacity to 50% in a variant */
  --brand-color-variant: hsl(var(--brand-hsl) / 50%);
}

Setelah sintaksis warna relatif, Anda dapat membuat warna merek dengan ruang warna atau sintaksis apa pun yang Anda perlukan, dan membuat varian setengah opasitas dengan kode yang jauh lebih sedikit. Juga jauh lebih mudah untuk membaca intent gaya dan sistem.

:root {
  --brand-color: hsl(300deg 75% 50%);
  --brand-color-variant: hsl(from var(--brand-color) h s l / 50%);
}

Postingan ini akan membantu Anda mempelajari sintaksis dan menunjukkan manipulasi warna umum.

Jika Anda lebih menyukai video, hampir semua artikel berikut dibahas dalam Tantangan GUI ini.

Ringkasan sintaksis

Tujuan sintaksis warna relatif adalah memungkinkan pengambilan warna dari warna lain. Warna dasar disebut warna asal, yaitu warna yang muncul setelah kata kunci from baru. Browser akan mengonversi dan memecah warna asal tersebut dan menawarkan bagian-bagian tersebut sebagai variabel untuk digunakan dalam definisi warna baru.

Diagram
sintaksis rgb(dari hijau r g b / alpha) ditampilkan, dengan panah
yang meninggalkan bagian atas warna hijau dan melengkung ke awal rgb fungsi,
panah ini dibagi menjadi 4 panah yang kemudian mengarah ke variabel yang relevan. Keempat
panah berwarna merah, hijau, biru, dan alfa. Merah dan biru memiliki nilai 0, hijau
adalah 128, dan alfa adalah 100%.

Diagram sebelumnya menunjukkan warna asal green yang dikonversi menjadi ruang warna warna baru, yang diubah menjadi angka individual yang direpresentasikan sebagai variabel r, g, b, dan alpha, yang kemudian langsung digunakan sebagai nilai warna rgb() baru.

Meskipun gambar ini menunjukkan perincian, proses, dan variabel, gambar juga tidak mengubah warnanya. Variabel dikembalikan ke warna tidak berubah, sehingga tetap menghasilkan warna hijau.

Kata kunci from

Bagian pertama sintaksis yang harus dipelajari adalah tambahan from <color> bagian untuk menentukan warna. Ini berlaku tepat sebelum Anda menentukan nilai. Berikut adalah contoh kode dengan semua yang telah ditambahkan adalah from green, tepat sebelum nilai untuk rgb() ditentukan.

.syntax-introduction_same-colors {
  color: green;
  color: rgb(0 128 0);
  color: rgb(from green r g b);    /* result = rgb(0 128 0) */
}

Kata kunci from tersebut, jika dilihat sebagai parameter pertama dalam notasi fungsional, mengubah definisi warna menjadi warna relatif. Setelah kata kunci from, CSS mengharapkan sebuah warna, warna yang akan menginspirasi warna berikutnya.

Konversi warna

Secara lebih sederhana, ia mengonversi warna hijau menjadi saluran r g dan b untuk digunakan dalam warna baru.

rgb(from green r g b)           /* r=0 g=128 b=0 */
rgb(from rgb(0 128 0) r g b);   /* r=0 g=128 b=0 */

Warna dari properti khusus

Membaca rgb from green sangat jelas dan mudah dipahami. Inilah sebabnya properti khusus dan sintaksis warna relatif sangat cocok karena Anda dapat menghilangkan misteri dari warna from. Secara umum, Anda juga tidak perlu mengetahui format warna warna properti kustom karena membuat warna baru dalam format pilihan.

rgb(from rgb(255 105 180) r g b) /* ????? */
rgb(from var(--hotpink) r g b)   /* clear */

Gunakan ruang warna pilihan Anda

Anda dapat memilih ruang warna dengan pilihan notasi warna fungsional.

rgb(from hsl(120 100% 25%) r g b)     /*  r=0   g=128  b=0    */
hsl(from hsl(120 100% 25%) h s l)     /*  h=120 s=100% l=25%  */
hwb(from hsl(120 100% 25%) h w b)     /*  h=120 w=0%   b=50%  */
lch(from hsl(120 100% 25%) l c h)     /*  l=46  c=68   h=134  */

Sintaksis warna relatif memiliki langkah konversi tersebut; warna setelah from dikonversi menjadi ruang warna seperti yang ditentukan di awal warna relatif. Input dan {i>output<i} tidak perlu cocok, yang sangat membebaskan.

Kemampuan untuk memilih ruang warna juga memberdayakan, karena memilih ruang warna cenderung lebih fokus pada jenis pergantian warna daripada preferensi. Preferensi terletak pada hasil, bukan format warna atau jenis saluran. Hal ini akan menjadi jauh lebih jelas di bagian yang menunjukkan kasus penggunaan, karena ruang warna yang berbeda unggul dalam tugas yang berbeda.

Mencampur, mencocokkan, menghilangkan, dan mengulangi variabel

Hal yang aneh tapi menarik tentang sintaksis ini, variabel tidak harus ditata kembali dan dapat diulang.

rgb(from green g g g)    /* rgb(128 128 128) */
rgb(from green b r g)    /* rgb(0 0 128) */
rgb(from green 0 0 g)    /* rgb(0 0 128) */

Opasitas sebagai variabel

Sintaksis tersebut juga memberikan opasitas sebagai variabel bernama alpha. Ini opsional, dan berjalan setelah / dalam notasi warna fungsional.

rgb(from #00800080 r g b / alpha)             /* alpha=50% */
rgb(from rgba(0,128,0,.5) r g b / alpha)      /* alpha=50% */
rgb(from rgb(0 128 0 / 50%) r g b / alpha)    /* alpha=50% */

Menggunakan calc() atau fungsi CSS lainnya pada variabel

Sejauh ini kita telah membuat warna hijau berulang kali. Mempelajari sintaksis, serta memahami langkah-langkah konversi dan penguraian. Sekarang saatnya untuk mengubah variabel, ubah output agar tidak sama dengan input.

green                              /*  h=120 s=100% l=25%  */
hsl(from green calc(h * 2) s l)    /*  h=240 s=100% l=25%  */

Sekarang berwarna biru laut! Hue dibuat dua kali lipat, mengambil hue 120 dan mengubahnya menjadi 240, yang sepenuhnya mengubah warna. Warna ini memutar hue di sepanjang roda warna, trik rapi yang dibuat sangat sederhana dengan ruang warna silinder seperti HSL, HWB, LCH, dan OKLCH.

Untuk melihat nilai saluran secara visual, sehingga Anda bisa mendapatkan perhitungan yang tepat tanpa menebak atau mengingat spesifikasi, coba alat nilai saluran sintaksis warna relatif. Pengungkapan ini mengungkap nilai setiap saluran berdasarkan sintaks yang Anda tentukan, memungkinkan Anda untuk mengetahui dengan tepat nilai apa yang Anda miliki untuk dimainkan.

Memeriksa dukungan browser

@supports (color: rgb(from white r g b)) {
  /* safe to use relative color syntax */
}

Kasus penggunaan dan demonstrasi

Contoh dan kasus penggunaan berikut memiliki banyak sintaksis alternatif untuk mencapai hasil yang serupa atau sama. Variasi berasal dari ruang warna dan saluran yang ditawarkannya.

Selain itu, banyak contoh yang akan menunjukkan penyesuaian warna dengan kata-kata by dan to. by yang berubah warna adalah perubahan warna relatif; perubahan yang menggunakan nilai variabel dan membuat penyesuaian berdasarkan nilainya saat ini. to yang berubah warna adalah perubahan warna absolut; perubahan yang tidak menggunakan nilai variabel dan sebagai gantinya menentukan nilai yang benar-benar baru.

Semua demo dapat ditemukan di koleksi Codepen ini.

Cerahkan warna

Ruang warna OKLCH, OKLAB, XYZ, atau sRGB memberikan hasil yang paling dapat diprediksi saat mencerahkan warna.

Cerahkan dengan jumlah tertentu

Contoh .lighten-by-25 berikut mengambil warna blue dan mengonversinya menjadi OKLCH, lalu mencerahkan biru dengan meningkatkan saluran l (kecerahan) dengan mengalikan nilai saat ini dengan 1.25. Hal ini mendorong cahaya biru ke arah putih sebesar 25%.

.lighten-by-25 {
  background: oklch(from blue calc(l * 1.25) c h);
}

Cerahkan ke nilai tertentu

Contoh berikut .lighten-to-75 tidak menggunakan saluran l untuk mencerahkan blue, melainkan sepenuhnya mengganti nilai dengan 75%.

.lighten-to-75 {
  background: oklch(from blue 75% c h);
}

Menggelapkan warna

Ruang warna yang sama efektif untuk mencerahkan warna, juga bagus untuk menggelapkan warna.

Gelar secukupnya

Contoh berikut .darken-by-25 mengambil warna biru dan mengubahnya menjadi OKLCH, lalu menggelapkan warna biru dengan mengurangi saluran l (kecerahan) sebesar 25% dengan mengalikan nilai dengan .75. Hal ini mendorong warna biru ke arah hitam sebesar 25%.

.darken-by-25 {
  background: oklch(from blue calc(l * .75) c h);
}

Menggelapkan ke nilai tertentu

Contoh berikut .darken-to-25 tidak menggunakan saluran l untuk menggelapkan blue, tetapi sepenuhnya mengganti nilai dengan 25%.

.darken-to-25 {
  background: oklch(from blue 25% c h);
}

Saturasi warna

Saturasi menurut jumlahnya

Contoh berikut .saturate-by-50 menggunakan s dari hsl() untuk meningkatkan vibransi orchid dengan 50% relatif.

.saturate-by-50 {
  background: hsl(from orchid h calc(s * 1.5) l);
}

Saturasi hingga jumlah tertentu

Contoh .saturate-to-100 berikut tidak menggunakan saluran s dari hsl(), tetapi menentukan nilai saturasi yang diinginkan. Dalam contoh ini, saturasi dinaikkan menjadi 100%.

.saturate-to-100 {
  background: hsl(from orchid h 100% l);
}

Menurunkan saturasi warna

Desaturasi dengan kadar tertentu

Contoh berikut .desaturate-by-half menggunakan s dari hsl() untuk mengurangi saturasi indigo hingga setengahnya.

.desaturate-by-half {
  background: hsl(from indigo h calc(s / 2) l);
}

Menurunkan saturasi ke nilai tertentu

Daripada menurunkan saturasi berdasarkan jumlah, Anda dapat menurunkan saturasi ke nilai tertentu yang diinginkan. Contoh .desaturate-to-25 berikut membuat warna baru berdasarkan indigo, tetapi menetapkan saturasi ke 25%.

.desaturate-to-25 {
  background: hsl(from indigo h 25% l);
}

Chroma meningkatkan warna

Efek ini mirip dengan saturasi warna, tetapi berbeda dalam beberapa cara. Pertama, ini adalah perubahan chroma dan bukan perubahan saturation, dan ini karena ruang warna yang dapat masuk ke dalam rentang dinamis tinggi tidak menggunakan saturasi. Ruang warna yang menampilkan chroma mampu menampilkan rentang dinamis tinggi, sehingga penulis dapat meningkatkan kecemerlangan warna lebih jauh daripada yang mampu dilakukan saturasi.

.increase-chroma {
  background: oklch(from orange l calc(c + .1) h);
}

Menyesuaikan opasitas warna

Membuat varian warna semi-transparan adalah salah satu penyesuaian warna yang paling umum dilakukan dalam sistem desain. Lihat contoh dalam pengantar artikel ini jika Anda melewatkannya, contoh ini menguraikan ruang masalah dengan sangat baik.

Menyesuaikan opasitas berdasarkan jumlah

.decrease-opacity-by-25 {
  background: rgb(from lime r g b / calc(alpha / 2));
}

Menyesuaikan opasitas ke nilai tertentu

.decrease-opacity-to-25 {
  background: rgb(from lime r g b / 25%);
}

Inversi warna

Inversi warna adalah fungsi penyesuaian warna yang umum ditemukan di library warna. Salah satu cara untuk melakukannya adalah dengan mengonversi warna ke RGB, lalu mengurangi 1 nilai setiap saluran.

.invert-each-rgb-channel {
  background: rgb(from yellow calc(255 - r) calc(255 - g) calc(255 - b));
}

Lengkapi warna

Jika tujuan Anda bukan untuk membalikkan warna melainkan melengkapinya, maka rotasi hue adalah kemungkinan yang Anda cari. Pilih ruang warna yang menawarkan hue sebagai sudut, lalu gunakan calc() untuk memutar hue sesuai jumlah yang Anda inginkan. Menemukan pelengkap warna dilakukan dengan memutar setengah putaran. Dalam hal ini, Anda dapat menambahkan atau mengurangi dari saluran h sebesar 180 untuk mencapai hasilnya.

.complementary-color {
  background: hsl(from blue calc(h + 180) s l);
}

Membuat kontras warna

Sebagai metode untuk mencapai rasio kontras warna yang dapat diakses, pertimbangkan L&midast; (Lstar). Cara ini menggunakan saluran kecerahan yang seragam secara persepsi (L) (kurang-lebih) dari LCH dan OKLCH, dalam calc(). Bergantung apakah Anda menargetkan kontras rendah, sedang, atau tinggi, L&midast; delta sekitar ~40, ~50, atau ~60.

Teknik ini berfungsi dengan baik di semua hue di LCH atau OKLCH.

Membuat kontras dengan warna yang lebih gelap

Class .well-contrasting-darker-color menunjukkan L* dengan delta 60. Karena warna asalnya adalah warna gelap (kecerahan bernilai rendah), 60% (.6) ditambahkan ke saluran kecerahan. Teknik ini digunakan untuk menemukan warna teks gelap yang kontras dan sama pada latar belakang terang.

.well-contrasting-darker-color {
  background: darkred;
  color: oklch(from darkred calc(l + .60) c h);
}

Membuat kontras pada warna yang lebih terang

Class .well-contrasting-lighter-color menunjukkan L* dengan delta juga 60%. Karena warna asalnya adalah warna terang (kecerahan bernilai tinggi), 0,60 dikurangi dari saluran kecerahan.

.well-contrasting-lighter-color {
  background: lightpink;
  color: oklch(from lightpink calc(l - .60) c h);
}

Palet warna

Sintaksis warna relatif sangat baik untuk membuat palet warna. Alat ini sangat berguna dan canggih karena jumlah ruang warna yang tersedia. Semua contoh berikut menggunakan OKLCH karena saluran kecerahan dapat diandalkan dan saluran hue dapat diputar tanpa efek samping. Contoh terakhir menunjukkan kombinasi penyesuaian kecerahan dan rotasi hue untuk hasil yang lebih menarik.

Buka contoh kode sumber untuk ini dan coba ubah --base-color, untuk melihat seberapa dinamis palet tersebut. Seru!

Jika Anda menyukai video ini, kami akan memberikan informasi mendalam tentang membuat palet warna di CSS dengan OKLCH di YouTube.

Palet monokromatik

Cara membuat palet monokrom adalah membuat palet dari hue yang sama, tetapi dengan variasi terang dan gelap. Warna tengah adalah warna sumber untuk palet, dengan dua varian lebih terang dan dua varian lebih gelap ditempatkan di kedua sisi.

:root {
  --base-color: deeppink;

  --color-0: oklch(from var(--base-color) calc(l + .20) c h); /* lightest */
  --color-1: oklch(from var(--base-color) calc(l + .10) c h);
  --color-2: var(--base-color);
  --color-3: oklch(from var(--base-color) calc(l - .10) c h);
  --color-4: oklch(from var(--base-color) calc(l - .20) c h); /* darkest */
}
Cobalah sekelompok palet yang dibuat dengan sintaks warna relatif dan OKLCH

Open Props, library variabel CSS gratis, menawarkan palet warna yang dibuat dengan strategi ini dan membuatnya mudah digunakan saat diimpor. Semuanya juga dibuat dari warna yang bisa Anda sesuaikan, cukup beri warna dan palet akan keluar!

Palet analog

Karena rotasi hue sangat mudah dengan OKLCH dan HSL, membuat palet warna analog menjadi mudah. Putar hue sesuai hasil yang Anda inginkan dan ubah warna dasar, lalu lihat palet baru yang dibuat oleh browser.

:root {
  --base-color: blue;

  --primary:   var(--base-color);
  --secondary: oklch(from var(--base-color) l c calc(h - 45));
  --tertiary:  oklch(from var(--base-color) l c calc(h + 45));
}

Palet triadik

Serupa dengan warna komplementer, palet warna triadik berlawanan tetapi harmonis dengan warna dasar yang diberikan. Jika warna pelengkap berada di sisi yang berlawanan dari warna, seperti garis lurus yang digambar melalui tengah roda warna, palet triadik seperti segitiga garis, menemukan 2 warna yang diputar sama rata dari warna dasar. Lakukan hal ini dengan memutar hue 120deg.

Ini adalah sedikit penyederhanaan teori warna, tetapi cukup untuk mengawali Anda ke palet triadik yang lebih kompleks jika tertarik.

:root {
  --base-color: yellow;
  --triad-1: oklch(from var(--base-color) l c calc(h - 120));
  --triad-2: oklch(from var(--base-color) l c calc(h + 120));
}

Palet tetradik

Palet tetradic terdiri dari empat warna yang dibagi merata di roda warna, sehingga menghasilkan palet tanpa nilai dominan yang jelas. Anda bisa menganggapnya juga, seperti dua pasang warna yang saling melengkapi. Jika digunakan dengan bijak, data tersebut bisa sangat bermakna.

Ini adalah sedikit penyederhanaan teori warna, tetapi cukup untuk mengawali Anda ke palet tetradik yang lebih kompleks jika tertarik.

:root {
  --base-color: lime;

  --color-1: var(--base-color);
  --color-2: oklch(from var(--base-color) l c calc(h + 90));
  --color-3: oklch(from var(--base-color) l c calc(h + 180));
  --color-4: oklch(from var(--base-color) l c calc(h + 270));
}

Monokrom dengan sedikit rotasi hue

Banyak pakar warna melanjutkan triknya. Masalahnya adalah, skala warna monokromatik bisa sangat membosankan. Solusinya adalah dengan menambahkan rotasi hue kecil atau besar ke setiap warna baru saat kecerahan diubah.

Contoh berikut mengurangi kecerahan sebesar 10% setiap swatch dan juga memutar hue sebesar 10 derajat. Hasilnya, palet hotpink hingga nila yang tampak menyatu dengan mulus seperti gradasi yang mungkin.

:root {
  --base-color: deeppink;

  --color-1: var(--base-color);
  --color-2: oklch(from var(--base-color) calc(l - .10) c calc(h - 10));
  --color-3: oklch(from var(--base-color) calc(l - .20) c calc(h - 20));
  --color-4: oklch(from var(--base-color) calc(l - .30) c calc(h - 30));
  --color-5: oklch(from var(--base-color) calc(l - .40) c calc(h - 40));
}
Coba papan peringkat ini yang dibuat dengan OKLCH dan rotasi hue

Antarmuka papan peringkat berikut menggunakan strategi rotasi hue ini. Setiap item daftar melacak indeksnya dalam dokumen sebagai variabel yang disebut --i. Indeks ini kemudian digunakan untuk menyesuaikan kroma, kecerahan, dan hue. Penyesuaiannya hanya sebesar 5% atau 5deg, jauh lebih halus daripada contoh di atas dengan deeppink, sehingga perlu mata yang tajam untuk memperhatikan alasan papan peringkat ini dapat memiliki rona apa pun dengan keanggunan seperti itu.

Pastikan untuk mengubah hue di penggeser di bawah papan peringkat, dan lihat sintaksis warna relatif menciptakan momen warna yang indah.

li {
  --_bg: oklch(
    /* decrease lightness as list grows */
    calc(75% - (var(--i) * 5%))

    /* decrease chroma as list grows */
    calc(.2 - (var(--i) * .01))

    /* lightly rotate the hue as the list grows */
    calc(var(--hue) - (var(--i) + 5))
  );
}