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

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

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

การสาธิต

หากชอบวิดีโอ นี่คือโพสต์นี้เวอร์ชัน YouTube

ภาพรวม

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

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

แบรนด์

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

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

เพื่อให้แนวคิดของการทำให้สีแบรนด์เข้มหรือจางลงโดยสมมติว่า 20% ต้องแยกค่าสี Hsl ทั้ง 3 แชแนลมาไว้ในพร็อพเพอร์ตี้ที่กำหนดเอง เช่น

* {
  --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 วิธีนี้ยังไม่เข้มเท่าสีที่ 1 ซึ่งดีพอๆ กับสีรอง และยังไม่ค่อยมีความอิ่มตัวน้อยกว่ามากด้วย

สีพื้นผิว

สีพื้นผิวคือพื้นหลัง เส้นขอบ และพื้นผิวตกแต่งอื่นๆ ที่มีข้อความตั้งอยู่หรือภายใน ในธีมสว่าง สีเหล่านี้จะเป็นสีอ่อน ซึ่งตรงข้ามกับสีข้อความซึ่งเป็นสีเข้ม ในการสร้างสีแสงด้วย 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 ต้องใช้ชิ้นส่วนเพื่อทำการคำนวณ ข้ามไปที่ส่วนเงา Rad เพื่อดูข้อมูลเพิ่มเติม

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

คุณไม่จำเป็นต้องไล่ดูทุกสีเพื่อสร้างสีไฟ ทั้งหมดรวมอยู่ในที่เดียวใน 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 มีประโยชน์อย่างยิ่งเพราะช่วยให้เราทำให้เงามืดลงได้ด้วยการเปลี่ยนตัวแปร 1 ตัว

* {
  --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% จะช่วยรักษาอัตราส่วนคอนทราสต์ของสีให้สูงอยู่เสมอ และในขณะเดียวกันก็เป็นเครื่องมือเล็กๆ น้อยๆ สำหรับการปรับในกรณีที่คะแนนต่ำ

ผมเรียกสิ่งนี้ว่า "Bump bump till ya Pass" ซึ่งเป็นการโต้ตอบของการเพิ่มค่าความสว่างจนกว่าเครื่องมือจะแสดงว่าฉันผ่าน

กด 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 เงาดังกล่าวสร้างขึ้นที่เครื่องมือ Smooth 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: var(--text1-light) ให้ใช้ color: var(--text1) ใน CSS จะมีการปรับและ Pivot ของสีทั้งหมด

เจาะลึกรูปแบบการเชื่อมโยงของธีมสว่างในบล็อกโค้ดต่อไปนี้ เชื่อมต่อพร็อพเพอร์ตี้ที่กำหนดเองทั่วไปกับสีเฉพาะสำหรับธีมสว่าง คราวนี้การใช้ 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: การสาธิต