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

ภาพรวมพื้นฐานเกี่ยวกับวิธีสร้างรูปแบบสีแบบไดนามิกและกำหนดค่าได้

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

สีพื้นผิว

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

สีพื้นผิว

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

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

เพื่อให้บรรลุเป้าหมายนี้ ฉันจึงสร้างตัวแปร 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) แทน 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 เพิ่มแถบเลื่อนสี demo สีสถานะ และโหมดคอนทราสต์สำหรับ no-preference, more และ less