การสร้างรูปแบบสี

ภาพรวมพื้นฐานของวิธีสร้างรูปแบบสีแบบไดนามิกที่กำหนดค่าได้

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

การสาธิต

หากต้องการดูวิดีโอ โปรดดูโพสต์นี้ใน YouTube

ภาพรวม

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

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

แบรนด์

โดยส่วนใหญ่แล้ว สีของแบรนด์จะได้รับการกำหนดไว้แล้วและส่งเป็น เลขฐานสิบหกหรือ RGB ความท้าทาย GUI นี้ มีสีพื้นฐานของแบรนด์เป็น #0af ก่อนอื่น สำหรับระบบสีนี้ ค่าเลขฐานสิบหก ต้องแปลงเป็น hsl

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

หากต้องการเปิดใช้แนวคิดการทำให้สีของแบรนด์เข้มขึ้นหรืออ่อนลง เช่น 20% คุณต้องแยก 3 แชแนลของค่าสี HSL ออกเป็นพร็อพเพอร์ตี้ที่กำหนดเองของตัวเอง ดังนี้

* {
  --brand-hue: 200;
  --brand-saturation: 100%;
  --brand-lightness: 50%;
}

CSS สามารถทำการคำนวณกับพร็อพเพอร์ตี้สีเหล่านั้นได้ เช่น calc(var(--brand-lightness) - 20%) เพื่อลดค่าความสว่างลง 20% ซึ่งเป็นพื้นฐานในการสร้าง รูปแบบสี เนื่องจาก CSS สามารถเก็บสีทั้งหมดไว้ในกลุ่มเฉดสีเดียวกันได้โดยการปรับ ค่าความอิ่มตัวและความสว่างของ HSL

ธีมสว่าง

ระบบจะทำเครื่องหมายตัวแปรสีแต่ละรายการด้วยรูปแบบที่ตรงกัน ในกรณีนี้ ระบบจะต่อท้ายแต่ละรายการด้วย -light

ตัวอย่างผลลัพธ์สุดท้ายของธีมสว่าง

แบรนด์

โดยเริ่มจากสีของแบรนด์ ระบบจะสร้างใหม่โดยการห่อพร็อพเพอร์ตี้ที่กำหนดเอง --brand-hue, --brand-saturation และ --brand-lightness ไว้ในวงเล็บของฟังก์ชัน hsl () โดยไม่ต้องคำนวณใดๆ

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

สีข้อความ

จากนั้น องค์ประกอบสำคัญของรูปแบบสีต้องมีสีข้อความ ในธีมสว่าง ข้อความ ควรเป็นสีเข้มมาก สังเกตว่าความสว่างของสีต่อไปนี้ต่ำกว่า 50%

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

--text1-light เนื่องจากสีจะมืดมากเมื่อมีความสว่าง 10% จึงคงความอิ่มตัว 100% ไว้ เพื่อให้สีของแบรนด์ยังคงมองเห็นได้ในสีน้ำเงินเข้ม

--text2-light สีนี้ไม่ได้เข้มเท่าสีแรก ซึ่งเป็นเรื่องดีเพราะเป็นสีรอง และยังมีความอิ่มตัวน้อยกว่ามากด้วย

สีพื้นผิว

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

* {
  --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 สีเนื่องจากสีตกแต่งมักจะต้องมีตัวแปรมากกว่า สำหรับช่วงเวลาแบบอินเทอร์แอกทีฟ เช่น :focus หรือ :hover หรือเพื่อสร้าง ลักษณะของเลเยอร์กระดาษ ในสถานการณ์เหล่านี้ การเปลี่ยน--surface2-lightเมื่อวางเมาส์เป็น--surface3-lightจะช่วยให้เมื่อวางเมาส์แล้วคอนทราสต์จะเพิ่มขึ้น (ความสว่าง 99% เป็น 92% ซึ่งทำให้เข้มขึ้น)

เงา

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

* {
  --surface-shadow-light: var(--brand-hue) 10% 20%;
  --shadow-strength-light: .02;
}

--surface-shadow-light ไม่ได้อยู่ในฟังก์ชัน HSL เนื่องจากระบบจะรวมค่า --shadow-strength เพื่อสร้างความทึบแสงบางส่วน และ CSS ต้องมี ชิ้นส่วนต่างๆ เพื่อทำการคำนวณ ข้ามไปที่ส่วนเงาที่สวยงามเพื่อดูข้อมูลเพิ่มเติม

สีอ่อนทั้งหมด

คุณไม่จำเป็นต้องค้นหาวิธีสร้างสีอ่อน เพราะสีทั้งหมดอยู่รวมกันใน 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;
}
ภาพหน้าจอของสีไฟทั้งหมด
แซนด์บ็อกซ์ใน CodePen

ธีมมืด

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

  1. โดยทั่วไปแล้ว ผู้ใช้จะอยู่ในโหมดมืดขณะใช้ธีมนี้ ดังนั้นให้ทดสอบในโหมดมืด
  2. สีควรลดความอิ่มตัวเพื่อไม่ให้สั่นบนหน้าจอเนื่องจากมีความเข้มมากเกินไป

ตัวอย่างผลลัพธ์สุดท้ายของธีมมืด

แบรนด์

ธีมสว่างใช้ค่าช่องสี HSL ของแบรนด์ทั้ง 3 โดยไม่มีการเปลี่ยนแปลง แต่ธีมมืดไม่ได้ใช้ ความอิ่มตัวลดลงครึ่งหนึ่งและความสว่างลดลง 50% แบบสัมพัทธ์

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

สีพื้นผิว

ในธีมมืด สีพื้นผิวควรเป็นสีเข้ม สีต่อไปนี้มีความสว่างและความอิ่มตัวต่ำ โดยพื้นผิวแรกจะเข้มที่สุดที่ 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%);
}

เงา

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

* {
  --surface-shadow-dark: var(--brand-hue) 50% 3%;
  --shadow-strength-dark: .8;
}

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

สีเข้มทั้งหมด

* {
  --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;
}
ภาพหน้าจอของสีเข้มทั้งหมด
แซนด์บ็อกซ์ใน CodePen

ธีมสลัว

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

ตัวอย่างผลลัพธ์สุดท้ายจากธีมสลัว

แบรนด์

* {
  --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;
}

หรี่สีทั้งหมด

* {
  --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;
}
ภาพหน้าจอของสีที่จางทั้งหมด
แซนด์บ็อกซ์ใน CodePen

สีที่เข้าถึงได้

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

ฉันเรียกเทคนิคนี้ว่า "ชนๆ จนกว่าจะผ่าน" ซึ่งเป็นการโต้ตอบด้วยการชนค่าความสว่างจนกว่าเครื่องมือจะแสดงว่าฉันผ่าน

กด Shift + ลูกศรลงเพื่อลดความสว่างและเพิ่มคอนทราสต์จนกว่าจะผ่าน

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

.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);
}
ภาพหน้าจอของพื้นผิวและข้อความที่จาง
ภาพหน้าจอของพื้นผิวและข้อความที่จางลงซึ่งจับคู่กับ VisBug

Rad Shadow

ธีมใช้คลาสยูทิลิตีที่เรียกว่า .rad-shadow เงาที่สร้างขึ้น ในเครื่องมือเงาแบบสมูทนี้ ซึ่งฉันชอบมาก ฉันนำข้อมูลโค้ดที่สร้างขึ้นมาปรับแต่งด้วยสีของตัวเองและ การคำนวณความทึบแสง เหตุผลที่ทำเช่นนี้ก็เพื่อสร้างเงาที่ฉันปรับได้ ภายในรูปแบบสีแต่ละแบบ

เงาแต่ละอันอยู่ติดกัน

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

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

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

การใช้รูปแบบสี

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

หากต้องการดำเนินการนี้ คุณควรใช้รูปแบบสีผ่านพร็อพเพอร์ตี้ที่กำหนดเองทั่วไปเท่านั้น ซึ่งเราจะกำหนดในอีกสักครู่ ด้วยวิธีนี้ ผู้ที่ใช้ตัวแปรการออกแบบจึงไม่ต้องกังวลว่าปัจจุบันมีการตั้งค่ารูปแบบสีใด เพียงแค่ใช้สีพื้นผิวและสีข้อความ ใช้ color: var(--text1) แทน color: var(--text1-light) การปรับและเปลี่ยน สีทั้งหมดจะดำเนินการในระดับที่สูงกว่ามากใน CSS

เมื่อเจาะลึกลงไป สไตล์การเชื่อมต่อของธีมสว่างในบล็อกโค้ดต่อไปนี้ จะเชื่อมต่อพร็อพเพอร์ตี้ที่กำหนดเองทั่วไปกับสีเฉพาะของธีมสว่าง ตอนนี้การใช้ var(--brand) ทั้งหมดจะใช้สีของแบรนด์แบบอ่อน

ธีมสว่าง (อัตโนมัติ)

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

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

ธีมมืด (อัตโนมัติ)

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

ธีมสว่าง

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

ธีมมืด

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

ธีมสลัว

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

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

บทสรุป

ตอนนี้คุณรู้วิธีที่ฉันทำแล้ว คุณจะทำอย่างไร 🙂

มาลองใช้แนวทางที่หลากหลายและเรียนรู้วิธีต่างๆ ในการสร้างสรรค์บนเว็บกัน สร้าง Codepen หรือโฮสต์เดโมของคุณเอง แล้วทวีตมาหาฉันพร้อมกับเดโมนั้น จากนั้นฉันจะเพิ่มเดโมลงในส่วน รีมิกซ์ของชุมชนด้านล่าง

แหล่งที่มา

รีมิกซ์ของชุมชน - @chris-kruining เพิ่มแถบเลื่อนเฉดสี สีสถานะ และโหมดคอนทราสต์สำหรับ no-preference, more และ less สาธิต