ภาพรวมพื้นฐานเกี่ยวกับวิธีสร้างรูปแบบสีแบบไดนามิกและกำหนดค่าได้
ในโพสต์นี้ เราอยากแชร์แนวคิดเกี่ยวกับวิธีจัดการรูปแบบสีหลายรูปแบบใน CSS ลองใช้เวอร์ชันเดโม
หากคุณชอบดูวิดีโอมากกว่า เรามีโพสต์นี้ในเวอร์ชัน YouTube ด้วย
ภาพรวม
เราจะสร้างระบบสีที่เข้าถึงได้ด้วยพร็อพเพอร์ตี้ที่กำหนดเองและ calc() เพื่อสร้างหน้าเว็บที่ปรับเปลี่ยนตามค่ากำหนดของผู้ใช้โดยที่ยังคงประสบการณ์การเขียนโค้ดที่เรียบง่ายไว้ เราเริ่มต้นด้วยสีแบรนด์พื้นฐานและสร้างระบบของตัวแปรจากสีดังกล่าว ซึ่งประกอบด้วยสีข้อความ 2 สี สีพื้นผิว 4 สี และเงาที่เข้ากัน
คู่มือนี้จะเริ่มต้นด้วยการกำหนดสีทั้งหมดสำหรับแต่ละรูปแบบสีก่อน โดยจะใช้เพื่อเปลี่ยนหน้าก็ต่อเมื่อถึงตอนท้ายสุดเท่านั้น
แบรนด์
บ่อยครั้งที่สีของแบรนด์ได้รับการกำหนดไว้แล้วและแสดงเป็น hex หรือ 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;
}
ธีมมืด
แบรนด์ส่วนใหญ่ไม่ได้เริ่มต้นด้วยธีมมืด แต่เป็นตัวแปรของธีมหลักซึ่งมักจะสว่างกว่า ในทางกลับกัน ผู้ใช้มักจะเลือกธีมมืดสำหรับบริบทที่แตกต่างกัน เช่น เวลากลางคืน ปัจจัยเหล่านี้ทำให้ฉันต้องคำนึงถึง 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%);
}
สีของพื้นผิว
ในธีมมืด สีของพื้นผิวควรเป็นสีเข้ม สีต่อไปนี้มีความสว่างและความอิ่มตัวต่ำ โดยพื้นผิวที่ 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;
}
ธีมมืด
รูปแบบสีนี้เน้นการประสานความสว่างและความอิ่มตัวของสี ควรมีความอิ่มตัวมากพอที่จะยังคงมองเห็นสีได้ แต่ก็ควรผ่านคะแนนคอนทราสต์แบบฉิวเฉียด เนื่องจากตั้งใจให้มีแสงสลัวและคอนทราสต์ต่ำอยู่แล้ว

แบรนด์
* {
--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;
}
สีที่เข้าถึงได้
โปรดสังเกตว่าความสว่างต่ำสุดในชุดสีข้อความมืดคือ 65% และความสว่างสูงสุดในพื้นผิวมืดคือ 25% ซึ่งเป็นพื้นที่ว่าง 40% ของความสว่างระหว่างสีทั้งสอง ในธีมสว่าง จะมีพื้นที่ว่าง 55% ในธีมสว่าง การรักษาความแตกต่างของความสว่างระหว่างข้อความและสีพื้นผิวไว้ที่ประมาณ 40-50% จะช่วยรักษาอัตราส่วนคอนทราสต์ของสีให้สูงได้ และยังเป็นตัวปรับที่ละเอียดอ่อนในกรณีที่คะแนนต่ำด้วย
ฉันเรียกวิธีนี้ว่า "เพิ่มค่าไปเรื่อยๆ จนกว่าจะผ่าน" ซึ่งเป็นการเพิ่มค่าความสว่างไปเรื่อยๆ จนกว่าเครื่องมือจะแสดงว่าผ่าน
ธีมแต่ละธีมที่สร้างขึ้นในชาเลนจ์นี้มีคะแนนคอนทราสต์ที่ผ่านเกณฑ์ รูปแบบสีมืดมีคอนทราสต์ต่ำที่สุด แต่ก็ยังผ่านข้อกำหนดขั้นต่ำ หากต้องการช่วยให้ผู้อื่นในทีมใช้สีที่ตัดกันได้ดี คุณควรสร้างชื่อคลาสที่จับคู่สีพื้นผิวกับสีข้อความที่เข้าถึงได้
.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);
}
Rad Shadow
ธีมใช้คลาสยูทิลิตีชื่อ .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) แทน 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: เดโม