ไวยากรณ์สีสัมพัทธ์ CSS

สร้างสีใหม่ตามช่องและค่าของสีอื่น

Adam Argyle
Adam Argyle

ใน Chrome 119 เป็นฟีเจอร์สีที่มีประสิทธิภาพมากจาก CSS Color Level 5 ไวยากรณ์สีแบบสัมพัทธ์จะสร้างเส้นทางที่ราบรื่นสำหรับการดัดแปลงสีภายใน CSS ซึ่งช่วยให้ผู้เขียนและนักออกแบบดำเนินการต่อไปนี้ได้

ก่อนไวยากรณ์สีแบบสัมพัทธ์ หากต้องการแก้ไขระดับความทึบของสี คุณต้องสร้างพร็อพเพอร์ตี้ที่กำหนดเองสำหรับแชแนลของสี ซึ่งโดยปกติจะเป็น HSL และประกอบเข้าด้วยกันเป็นสีสุดท้ายและสีของตัวแปรสุดท้าย ซึ่งหมายความว่าต้องจัดการชิ้นงานสีจํานวนมาก ซึ่งอาจกลายเป็นภาระได้อย่างรวดเร็ว

: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%);
}

หลังจากไวยากรณ์สีสัมพัทธ์ คุณสามารถสร้างสีของแบรนด์ด้วยพื้นที่สีหรือไวยากรณ์ที่ต้องการ และสร้างตัวแปรที่มีความทึบแสงครึ่งหนึ่งโดยใช้โค้ดน้อยกว่ามาก นอกจากนี้ ยังช่วยให้อ่านความตั้งใจของรูปแบบและระบบได้ง่ายขึ้นมาก

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

โพสต์นี้จะช่วยคุณเรียนรู้ไวยากรณ์และสาธิตการปรับสีทั่วไป

หากต้องการดูวิดีโอ บทความต่อไปนี้เกือบทั้งหมดจะอยู่ใน GUI Challenge นี้

ภาพรวมของไวยากรณ์

เป้าหมายของไวยากรณ์สีแบบสัมพัทธ์คือการอนุญาตให้ดึงข้อมูลสีจากสีอื่น สีฐานเรียกว่าสีต้นทาง ซึ่งเป็นสีที่อยู่หลังคีย์เวิร์ด from ใหม่ เบราว์เซอร์จะแปลงและแยกสีต้นทางนี้ออกเป็นส่วนๆ และเสนอส่วนต่างๆ เป็นตัวแปรเพื่อใช้ในคำจำกัดความสีใหม่

แสดงแผนภาพไวยากรณ์ rgb(จากสีเขียว r g b / alpha) พร้อมลูกศรที่ออกจากด้านบนของสีเขียวและโค้งไปยังจุดเริ่มต้น rgb ของฟังก์ชัน ซึ่งลูกศรนี้จะแยกออกเป็น 4 ลูกศรที่ชี้ไปยังตัวแปรที่เกี่ยวข้อง โดยลูกศร 4 หัวมีสีแดง เขียว น้ำเงิน และออลฟา สีแดงและน้ำเงินมีค่าเป็น 0 สีเขียวมีค่าเป็น 128 และอัลฟ่ามีค่าเป็น 100%

แผนภาพก่อนหน้าแสดงสีต้นทาง green ที่กำลังแปลงเป็นพื้นที่สีของสีใหม่ เปลี่ยนเป็นตัวเลขแต่ละตัวที่แสดงเป็นตัวแปร r, g, b และ alpha จากนั้นจึงนำไปใช้เป็นค่าของสี rgb() ใหม่โดยตรง

แม้ว่ารูปภาพนี้จะแสดงรายละเอียด กระบวนการ และตัวแปร แต่ก็ไม่ได้เปลี่ยนสี ระบบจะใส่ตัวแปรกลับเข้าไปในสีโดยไม่มีการเปลี่ยนแปลงใดๆ ส่งผลให้ยังคงเป็นสีเขียว

คีย์เวิร์ด from

ส่วนแรกของไวยากรณ์ที่ควรทราบคือส่วน from <color> เพิ่มเติมจากการกำหนดสี อยู่ก่อนที่คุณระบุค่า ต่อไปนี้คือตัวอย่างโค้ดที่เพิ่มทั้งหมดคือ from green อยู่ก่อนการระบุค่าสำหรับ rgb()

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

เมื่อเห็นคีย์เวิร์ด from นั้นในฐานะพารามิเตอร์แรกในนิพจน์ฟังก์ชัน ระบบจะเปลี่ยนคำจำกัดความสีให้เป็นสีแบบสัมพัทธ์ หลังจากคีย์เวิร์ด from แล้ว CSS จะคาดหวังสี ซึ่งเป็นสีที่จะสร้างแรงบันดาลใจให้กับสีถัดไป

การแปลงสี

กล่าวอย่างง่ายคือ เครื่องมือนี้จะแปลงสีเขียวเป็นช่อง r g และ b เพื่อใช้ในสีใหม่

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 */

สีจากพร็อพเพอร์ตี้ที่กำหนดเอง

การอ่าน rgb from green นั้นชัดเจนและเข้าใจง่ายมาก ด้วยเหตุนี้ คุณสมบัติที่กำหนดเองและไวยากรณ์สีแบบสัมพัทธ์จึงเข้ากันได้ดี เนื่องจากคุณทำให้สี from เข้าใจง่าย นอกจากนี้ โดยทั่วไปคุณไม่จําเป็นต้องทราบรูปแบบสีของสีพร็อพเพอร์ตี้ที่กําหนดเอง เนื่องจากคุณกําลังสร้างสีใหม่ในรูปแบบที่เลือก

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

ทำงานในพื้นที่สีที่ต้องการ

คุณเลือกพื้นที่สีด้วยรูปแบบการเขียนสีแบบฟังก์ชันที่ต้องการได้

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  */

ไวยากรณ์สีสัมพัทธ์มีขั้นตอนการเปลี่ยนรูปแบบดังกล่าว สีหลัง from จะเปลี่ยนเป็นพื้นที่สีตามที่ระบุไว้ที่จุดเริ่มต้นของสีสัมพัทธ์ อินพุตและเอาต์พุตไม่จำเป็นต้องตรงกัน ซึ่งช่วยให้คุณมีอิสระอย่างมาก

ความสามารถในการเลือกพื้นที่สียังช่วยให้คุณมีอำนาจมากขึ้นด้วย เนื่องจากการเลือกพื้นที่สีมักจะเน้นที่ประเภทของการเปลี่ยนสีมากกว่าความชอบ ค่ากำหนดจะอยู่ในผลลัพธ์ ไม่ใช่รูปแบบสีหรือประเภทแชแนล เรื่องนี้จะชัดเจนขึ้นมากในส่วนที่แสดงกรณีการใช้งาน เนื่องจากพื้นที่สีแต่ละแบบมีความเชี่ยวชาญในงานที่แตกต่างกัน

ผสม จับคู่ ละเว้น และนําตัวแปรมาใช้ซ้ำ

สิ่งที่แปลกแต่น่าตื่นเต้นเกี่ยวกับไวยากรณ์นี้คือ คุณไม่จำเป็นต้องจัดเรียงตัวแปรกลับเข้าลำดับเดิมและสามารถใช้ซ้ำได้

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) */

ความทึบแสงเป็นตัวแปร

ไวยากรณ์นี้ยังมีค่าระดับทึบเป็นตัวแปรชื่อ alpha ด้วย ซึ่งไม่บังคับ และจะอยู่หลัง / ในเครื่องหมายนิพจน์สี

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% */

ใช้ calc() หรือฟังก์ชัน CSS อื่นๆ ในตัวแปร

จนถึงตอนนี้ เราสร้างสีเขียวซ้ำๆ กัน เรียนรู้ไวยากรณ์ ทำความคุ้นเคยกับขั้นตอนการเปลี่ยนรูปแบบและการแยกโครงสร้าง ตอนนี้ถึงเวลาแก้ไขตัวแปรและเปลี่ยนเอาต์พุตให้แตกต่างจากอินพุต

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

ตอนนี้เป็นสีน้ำเงินแล้ว ปรับสีเป็น 2 เท่า โดยนำสี 120 มาเปลี่ยนเป็น 240 ซึ่งทำให้สีเปลี่ยนไปอย่างสิ้นเชิง ซึ่งจะหมุนสีตามวงล้อสี นี่เป็นเทคนิคที่ยอดเยี่ยมที่ทำได้ง่ายๆ ด้วยพื้นที่สีทรงกระบอก เช่น HSL, HWB, LCH และ OKLCH

หากต้องการดูค่าของแชแนลเพื่อให้คำนวณได้อย่างถูกต้องโดยไม่ต้องเดาหรือจำข้อมูลจำเพาะ ให้ลองใช้เครื่องมือค่าแชแนลไวยากรณ์สีสัมพัทธ์นี้ ซึ่งจะแสดงค่าของช่องแต่ละช่องตามไวยากรณ์ที่คุณระบุ เพื่อให้คุณทราบว่ามีตัวเลือกค่าใดบ้าง

ตรวจสอบการรองรับเบราว์เซอร์

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

กรณีการใช้งานและการสาธิต

ตัวอย่างและกรณีการใช้งานต่อไปนี้มีไวยากรณ์ทางเลือกมากมายเพื่อให้ได้ผลลัพธ์ที่คล้ายกันหรือเหมือนกัน ความแตกต่างมาจากพื้นที่สีและช่องที่นำเสนอ

นอกจากนี้ ตัวอย่างจำนวนมากจะแสดงการปรับสีด้วยข้อความ by และ to by ที่เปลี่ยนสีเป็นการเปลี่ยนแปลงสีแบบสัมพัทธ์ ซึ่งเป็นการเปลี่ยนแปลงที่ใช้ค่าของตัวแปรและทำการปรับเปลี่ยนตามค่าปัจจุบันของตัวแปร to ที่เปลี่ยนสีเป็นการเปลี่ยนแปลงสีแบบสัมบูรณ์ ซึ่งเป็นการเปลี่ยนแปลงที่ไม่ได้ใช้ค่าของตัวแปร แต่ระบุค่าใหม่ทั้งหมดแทน

ดูตัวอย่างทั้งหมดได้ในคอลเล็กชัน Codepen นี้

เพิ่มความสว่างให้กับสี

พื้นที่สี OKLCH, OKLAB, XYZ หรือ sRGB ให้ผลลัพธ์ที่คาดการณ์ได้มากที่สุดเมื่อปรับสีให้สว่างขึ้น

ปรับให้สว่างขึ้นตามจำนวน

ตัวอย่างต่อไปนี้ .lighten-by-25 นำสี blue มาแปลงเป็น OKLCH จากนั้นปรับสีน้ำเงินให้อ่อนลงโดยเพิ่มแชแนล l (ความสว่าง) โดยการคูณค่าปัจจุบันด้วย 1.25 ซึ่งจะเพิ่มความสว่างของสีน้ำเงินให้ใกล้เคียงกับสีขาวขึ้น 25%

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

เพิ่มความสว่างเป็นค่าที่ต้องการ

ตัวอย่างต่อไปนี้ .lighten-to-75 ไม่ได้ใช้แชแนล l เพื่อทำให้ blue สว่างขึ้น แต่แทนที่ด้วยค่า 75% ทั้งหมด

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

ทำให้สีเข้มขึ้น

พื้นที่สีเดียวกันที่มีประสิทธิภาพในการทำให้สีอ่อนลงก็เหมาะอย่างยิ่งสำหรับการทำให้สีเข้มขึ้นด้วย

ปรับความเข้มตามจำนวน

ตัวอย่างต่อไปนี้ .darken-by-25 นำสีน้ำเงินไปแปลงเป็น OKLCH จากนั้นทำให้สีน้ำเงินเข้มขึ้นโดยลดแชแนล l (ความสว่าง) ลง 25% ด้วยการคูณค่าด้วย .75 ซึ่งจะเปลี่ยนสีน้ำเงินให้เข้มขึ้น 25%

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

ปรับให้เข้มขึ้นเป็นค่าที่ระบุ

ตัวอย่างต่อไปนี้ .darken-to-25 ไม่ได้ใช้แชแนล l เพื่อทำให้ blue เข้มขึ้น แต่แทนที่ด้วยค่า 25% ทั้งหมด

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

ทำให้สีมีความอิ่มตัว

เพิ่มสีให้อิ่มตัวตามจำนวน

ตัวอย่างต่อไปนี้ .saturate-by-50 ใช้ s จาก hsl() เพื่อเพิ่มความมีชีวิตชีวาของ orchid โดยประมาณ 50%

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

ทำให้อิ่มตัวตามจำนวนที่ต้องการ

ตัวอย่างต่อไปนี้ .saturate-to-100 ไม่ได้ใช้แชแนล s จาก hsl() แต่ระบุค่าความอิ่มตัวของสีที่ต้องการแทน ในตัวอย่างนี้ ระบบจะเพิ่มค่าความอิ่มตัวเป็น 100%

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

ลดความอิ่มตัวของสี

ลดความอิ่มตัวของสีตามจำนวน

ตัวอย่างต่อไปนี้ .desaturate-by-half ใช้ s จาก hsl() เพื่อลดความอิ่มตัวของ indigo ลงครึ่งหนึ่ง

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

ลดความอิ่มตัวของสีเป็นค่าที่ต้องการ

คุณสามารถทำให้สีซีดตามค่าที่ต้องการได้แทนที่จะปรับตามจำนวน ตัวอย่างต่อไปนี้ .desaturate-to-25 จะสร้างสีใหม่โดยอิงตาม indigo แต่ตั้งค่าความอิ่มตัวเป็น 25%

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

เพิ่มสี

เอฟเฟกต์นี้คล้ายกับการปรับสีให้อิ่มตัว แต่มีความแตกต่างกันอยู่ 2 อย่าง ประการแรก การเปลี่ยนแปลงนี้เกี่ยวข้องกับchroma ไม่ใช่saturation เนื่องจากพื้นที่สีที่เพิ่มเป็น High Dynamic Range จะไม่ใช้ความอิ่มตัว พื้นที่สีที่มี chroma รองรับช่วงไดนามิกสูง ซึ่งช่วยให้ผู้เขียนเพิ่มสีสันให้ภาพได้มากกว่าที่ความอิ่มตัวจะทำได้

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

ปรับความทึบแสงของสี

การสร้างตัวแปรสีแบบโปร่งแสงบางส่วนเป็นหนึ่งในการปรับสีที่พบบ่อยที่สุดในระบบการออกแบบ โปรดดูตัวอย่างในส่วนนําเข้าของบทความนี้หากพลาดไป ตัวอย่างนี้อธิบายขอบเขตของปัญหาได้ดีมาก

ปรับความทึบแสงตามจำนวน

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

ปรับความทึบแสงเป็นค่าที่เจาะจง

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

สลับสี

การกลับสีเป็นฟังก์ชันการปรับสีทั่วไปที่พบในคลังสี วิธีหนึ่งในการทำเช่นนี้คือการแปลงสีเป็น RGB แล้วลบค่าของแต่ละช่องออกจาก 1

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

ใช้สีเสริม

หากเป้าหมายของคุณไม่ใช่การกลับสี แต่ต้องการเสริมสี ให้ลองใช้การหมุนสี เลือกพื้นที่สีซึ่งแสดงสีเป็นมุม จากนั้นใช้ calc() เพื่อหมุนสีตามจำนวนที่ต้องการ การหาสีเสริมทำได้โดยการหมุนครึ่งรอบ ในกรณีนี้คุณสามารถบวกหรือลบจากช่อง h ด้วย 180 เพื่อให้ได้ผลลัพธ์ที่ต้องการ

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

คอนทราสต์สี

ลองใช้ L&midast; (Lstar) เป็นวิธีในการทำให้อัตราส่วนคอนทราสต์ของสีเป็นไปตามข้อกำหนดการช่วยเหลือพิเศษ ซึ่งใช้ช่องความสว่าง (L) ที่รับรู้ได้ (โดยประมาณ) จาก LCH และ OKLCH ใน calc() ความแตกต่างของ L&midast; จะอยู่ที่ประมาณ 40, 50 หรือ 60 ขึ้นอยู่กับว่าคุณกําลังกําหนดเป้าหมายที่คอนทราสต์ต่ำ ปานกลาง หรือสูง

เทคนิคนี้ใช้ได้กับเฉดสีใดก็ได้ใน LCH หรือ OKLCH

คอนทราสต์กับสีเข้ม

คลาส .well-contrasting-darker-color แสดง L* ที่มีค่าเดลต้า 60 เนื่องจากสีต้นทางเป็นสีเข้ม (ความสว่างที่มีค่าต่ำ) ระบบจึงเพิ่ม 60% (.6) ลงในแชแนลความสว่าง เทคนิคนี้ใช้เพื่อค้นหาสีข้อความสีเข้มที่มีสีโทนเดียวกันและตัดกันได้ดีบนพื้นหลังสีอ่อน

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

คอนทราสต์สีอ่อน

คลาส .well-contrasting-lighter-color แสดง L* ที่มีค่าเดลต้า 60% ด้วยเช่นกัน เนื่องจากสีต้นทางเป็นสีอ่อน (ความสว่างสูง) ระบบจึงหัก .60 ออกจากช่องความสว่าง

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

ชุดสี

ไวยากรณ์สีแบบสัมพัทธ์สร้างชุดสีได้ดีมาก ซึ่งมีประโยชน์และมีประสิทธิภาพอย่างยิ่งเนื่องจากมีจำนวนพื้นที่สีที่พร้อมใช้งาน ตัวอย่างต่อไปนี้ทั้งหมดใช้ OKLCH เนื่องจากช่องความสว่างเชื่อถือได้และช่องสีสามารถหมุนได้โดยไม่มีผลข้างเคียง ตัวอย่างสุดท้ายแสดงการผสมผสานการปรับความสว่างและการหมุนสีเพื่อให้ได้ผลลัพธ์ที่น่าสนใจยิ่งขึ้น

เปิดซอร์สโค้ดตัวอย่างของพาเลตเหล่านี้ แล้วลองเปลี่ยน --base-color เพื่อดูว่าพาเลตเหล่านี้เป็นแบบไดนามิกเพียงใด สนุกดี

หากชอบวิดีโอ เรามีข้อมูลเชิงลึกเกี่ยวกับการสร้างแพตเทลสีใน CSS ด้วย OKLCH บน YouTube

พาเล็ตสีเดียว

การสร้างชุดสีโมโนโครมคือการสร้างชุดสีจากเฉดสีเดียวกันทั้งหมด แต่มีระดับความสว่างและความมืดแตกต่างกัน สีกลางคือสีต้นฉบับสำหรับชุดสี โดยจะมีตัวแปรที่อ่อนกว่า 2 สีและเข้มกว่า 2 สีวางไว้ด้านข้าง

: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 */
}
ลองใช้ชุดสีต่างๆ ที่สร้างขึ้นด้วยไวยากรณ์สีแบบสัมพัทธ์และ OKLCH

Open Props เป็นคลังตัวแปร CSS ที่ไม่มีค่าใช้จ่าย ซึ่งมีแพลตเทลสีที่สร้างโดยใช้กลยุทธ์นี้และทำให้ใช้งานได้ง่ายด้วยการนําเข้า นอกจากนี้ ฟีเจอร์นี้ยังสร้างจากสีที่คุณปรับแต่งได้ เพียงกำหนดสีให้ฟีเจอร์ก็จะสร้างจานสีขึ้นมา

พาเล็ตแบบคล้ายกัน

เนื่องจากการหมุนสีทำได้ง่ายมากด้วย OKLCH และ HSL คุณจึงสร้างชุดสีแบบคู่กันได้ง่ายๆ หมุนความเข้มของสีตามจำนวนที่ต้องการ แล้วเปลี่ยนสีฐาน จากนั้นดูว่าเบราว์เซอร์สร้างจานสีใหม่อย่างไร

: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));
}

พาเลตชุดสีสามเหลี่ยม

ชุดสีไตรแอดมีลักษณะคล้ายกับสีเสริม เป็นการหมุนสีตรงข้ามกันแต่กลมกลืนกันโดยอิงตามสีฐาน เมื่อสีเสริมกันอยู่ฝั่งตรงข้ามของสีหนึ่งๆ เช่น เส้นตรงที่ลากผ่านตรงกลางของวงล้อสี พาเลตแบบ 3 สีจะเหมือนกับรูปสามเหลี่ยมของเส้น โดยหาสี 2 สีที่ปรับจากสีฐานเท่าๆ กัน โดยหมุนสี 120deg

นี่เป็นทฤษฎีสีที่เข้าใจง่ายขึ้นเล็กน้อย แต่ก็เพียงพอที่จะเริ่มต้นใช้งานชุดสีไตรadic ที่ซับซ้อนมากขึ้นได้หากสนใจ

: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));
}

พาเลตแบบ 4 สี

จานสี Tetradic คือชุดสี 4 สีที่แบ่งเท่าๆ กันบนวงล้อสี ซึ่งทำให้เป็นชุดสีที่ไม่มีสีเด่นอย่างชัดเจน หรือจะมองว่าเป็นคู่สีเสริมกันก็ได้ การใช้อย่างชาญฉลาดจะทําให้ข้อมูลมีความหมายมาก

นี่เป็นทฤษฎีสีที่เข้าใจง่ายขึ้นเล็กน้อย แต่ก็เพียงพอที่จะเริ่มต้นใช้งานชุดสี 4 สีที่ซับซ้อนมากขึ้นได้หากสนใจ

: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));
}

โทนเดียวที่มีการหมุนสีเล็กน้อย

ผู้เชี่ยวชาญด้านสีหลายคนใช้เคล็ดลับนี้ แต่ปัญหาคือ การใช้โทนสีเดียวอาจดูน่าเบื่อ วิธีแก้ปัญหาคือเพิ่มการหมุนสีเล็กน้อยหรือมากลงในสีใหม่แต่ละสีเมื่อความสว่างมีการเปลี่ยนแปลง

ตัวอย่างต่อไปนี้จะลดความสว่างลง 10% สำหรับแต่ละตัวอย่างสี และเปลี่ยนเฉดสี 10 องศา ผลลัพธ์ที่ได้คือ พาเล็ตสีชมพูสดไปจนถึงสีครามที่ดูกลมกลืนกันราวกับเป็นสีไล่ระดับ

: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));
}
ลองใช้ลีดเดอร์บอร์ดนี้ที่สร้างด้วย OKLCH และการหมุนสี

อินเทอร์เฟซตารางอันดับต่อไปนี้ใช้กลยุทธ์การเปลี่ยนสีนี้ รายการในลิสต์แต่ละรายการจะติดตามดัชนีในเอกสารเป็นตัวแปรชื่อ --i จากนั้นจะใช้ดัชนีนี้เพื่อปรับความเข้ม ความสว่าง และสี การปรับมีเพียง 5% หรือ 5 องศา ซึ่งน้อยกว่าตัวอย่างด้านบนที่ใช้สีชมพูเข้มมาก จึงต้องสังเกตให้ดีถึงจะเห็นว่าทำไมลีดเดอร์บอร์ดนี้จึงใช้เฉดสีใดก็ได้อย่างสง่างาม

อย่าลืมเปลี่ยนสีในแถบเลื่อนใต้ตารางอันดับ และดูว่ารูปแบบสีสัมพัทธ์สร้างช่วงเวลาที่มีสีสันสวยงามได้อย่างไร

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))
  );
}