HSL color model
(hue, saturation, lightness) คือรูปแบบสีที่ช่วยให้นักพัฒนาทำงานกับสีใน CSS ได้ง่ายและเข้าใจได้มากกว่า RGB มาก แทนที่จะต้องลองผิดลองถูกกับค่า red, green, blue ให้ได้สีที่ต้องการ HSL ให้คุณอธิบายสีแบบที่สมองมนุษย์คิดตามธรรมชาติ นั่นคือเลือกสี กำหนดความสดใส แล้วค่อยปรับความสว่างหรือความมืด ความแตกต่างในแนวคิดนี้เองที่ทำให้นักพัฒนาจำนวนมากหันมาใช้
hsl()
แทน
rgb()
ครับ
สารบัญ
RGB vs HSL - ความแตกต่างหลัก
RGB กำหนดสีด้วยการผสมช่องแสงสามช่อง ได้แก่ red, green และ blue โดยแต่ละค่าอยู่ในช่วง 0 ถึง 255 ปัญหาคือนี่คือวิธีที่หน้าจอแสดงผล pixel ไม่ใช่วิธีที่มนุษย์รับรู้สี ถ้าอยากได้สีน้ำเงินที่อ่อนกว่าเดิมนิดหน่อยใน RGB คุณต้องปรับทั้งสามค่าในสัดส่วนที่พอดี ไม่มีปุ่มเดียวให้หมุนครับ
HSL สะท้อนวิธีที่คนทั่วไปอธิบายสีในชีวิตจริง:
- Hue - สีจริง ๆ แสดงเป็นองศาบนวงล้อสี 360 องศา โดย red คือ 0, green คือ 120 และ blue คือ 240
- Saturation - ความสดใสหรือความจืดของสี ตั้งแต่ 0% (เทาล้วน) ถึง 100% (สดใสเต็มที่)
- Lightness - ความสว่างหรือความมืดของสี ตั้งแต่ 0% (ดำ) ถึง 100% (ขาว) โดย 50% คือสี "บริสุทธิ์"
นี่คือสีน้ำเงินกลาง ๆ เดียวกันที่แสดงในทั้งสองรูปแบบ:
/* RGB - what do these numbers even mean at a glance? */
color: rgb(70, 130, 180);
/* HSL - instantly readable: blue hue, moderate saturation, medium lightness */
color: hsl(207, 44%, 49%);
ทั้งคู่ให้สีน้ำเงินเหล็กเหมือนกัน แต่เฉพาะ HSL เท่านั้นที่บอกข้อมูลที่เป็นประโยชน์ได้ทันที hue คือ 207 (โทนน้ำเงิน), saturation ปานกลางที่ 44% และ lightness อยู่กลาง ๆ ที่ 49% คุณเข้าใจได้เลยโดยไม่ต้องเปิด color picker ครับ
| คุณสมบัติ | RGB | HSL |
|---|---|---|
| มนุษย์อ่านออกได้ | แทบไม่ได้ | ได้เลย |
| ทำให้สีสว่างขึ้น/มืดลง | ต้องปรับ 3 ค่า | ปรับแค่ lightness เดียว |
| เปลี่ยน saturation | คำนวณใหม่ทั้ง 3 ค่า | ปรับแค่ saturation เดียว |
| สร้าง color palette | ลองผิดลองถูก | หมุน hue เป็นองศา |
| Theming ด้วย CSS variables | ยุ่งยาก | กระชับและคาดเดาได้ |
Syntax ของ HSL ใน CSS
ฟังก์ชัน
hsl()
ใน CSS รองรับมาตั้งแต่ CSS3 แล้วครับ และใน syntax สมัยใหม่ (CSS Color Level 4) ยังสามารถใส่พารามิเตอร์ alpha ได้โดยตรงภายใน
hsl()
เลย ทำให้
hsla()
แทบไม่จำเป็นอีกต่อไป:
/* Classic syntax */
color: hsl(207, 44%, 49%);
/* With alpha (transparency) - old way */
color: hsla(207, 44%, 49%, 0.8);
/* Modern CSS Color Level 4 syntax - commas optional, alpha with slash */
color: hsl(207 44% 49%);
color: hsl(207 44% 49% / 0.8);
color: hsl(207 44% 49% / 80%);
เบราว์เซอร์หลักทุกตัวรองรับทั้งสอง syntax ครับ รูปแบบที่ไม่ใช้ comma คือทิศทางที่ CSS กำลังมุ่งไป แต่รูปแบบที่ใช้ comma ก็ยังทำงานได้ทุกที่รวมถึง Internet Explorer 9 ขึ้นไป
ทำไม HSL ถึงได้เปรียบในการพัฒนา UI
พลังที่แท้จริงของ HSL จะเห็นชัดเมื่อคุณต้องสร้างสีหลายเฉดจากสีเดิม ซึ่งเป็นสิ่งที่เกิดขึ้นบ่อยมากในงาน UI ครับ
สร้าง color palette ได้ในไม่กี่วินาที
สมมติว่าสีแบรนด์ของคุณคือสีเขียวสดที่
hsl(140, 70%, 45%)
แล้วคุณต้องการ hover state, disabled state และ background tint ที่อ่อน ๆ ด้วย HSL คุณแตะแค่ค่าเดียวในแต่ละครั้ง:
--color-base: hsl(140, 70%, 45%); /* base green */
--color-hover: hsl(140, 70%, 38%); /* darker - just lower lightness */
--color-disabled: hsl(140, 20%, 65%); /* washed out - lower saturation */
--color-tint: hsl(140, 70%, 92%); /* very light background tint */
ลองทำแบบนี้ให้ได้ผลแม่นยำด้วย RGB โดยไม่เปิด color picker ดูครับ มันยากจริง ๆ เพราะไม่มีแกนที่แยกออกมาให้ปรับได้เลย
สี Analogous และ Complementary
เนื่องจาก hue คือองศาบนวงล้อสี การสร้าง palette ที่กลมกลืนกันจึงเป็นแค่การคำนวณเลขธรรมดา สี analogous อยู่ภายใน 30 องศาจากกัน ส่วนสี complementary อยู่ห่างกัน 180 องศา:
--primary: hsl(210, 80%, 50%); /* blue */
--analogous-1: hsl(180, 80%, 50%); /* cyan - 30 degrees left */
--analogous-2: hsl(240, 80%, 50%); /* purple - 30 degrees right */
--complementary: hsl(30, 80%, 50%); /* orange - 180 degrees opposite */
saturation และ lightness คงที่เหมือนกันทุกสี ทำให้สีทั้งหมดดูเป็นกลุ่มเดียวกันอย่างกลมกลืน นี่คือวิธีที่ design system อย่าง Tailwind CSS และ Material Design ใช้สร้าง color scale แบบ programmatic ครับ
ตัวอย่างการใช้งาน CSS จริง
CSS custom properties ร่วมกับค่าของ HSL
หนึ่งใน pattern ที่ทรงพลังที่สุดของ HSL คือการแยกค่าทั้งสามออกเป็น CSS custom properties แต่ละตัว ช่วยให้คุณนำกลับมาประกอบใหม่ได้ทุกที่และปรับแต่ละค่าได้ทันที:
:root {
--brand-h: 210;
--brand-s: 80%;
--brand-l: 50%;
--brand-color: hsl(var(--brand-h), var(--brand-s), var(--brand-l));
}
.button {
background-color: var(--brand-color);
}
.button:hover {
/* Just override lightness - no need to redefine the whole color */
background-color: hsl(var(--brand-h), var(--brand-s), 40%);
}
.button:disabled {
background-color: hsl(var(--brand-h), 20%, 70%);
}
hsl()
คุณต้องใช้ comma:
hsl(var(--h), var(--s), var(--l))
ครับ เพราะ syntax สมัยใหม่แบบไม่ใช้ comma ยังไม่รองรับการใช้
var()
ภายใน
hsl()
ในทุกเบราว์เซอร์
สร้าง tonal scale ครบชุด
design system มักต้องการสี 9-10 เฉดจากสีเดียว (เช่น scale 50 ถึง 950 ของ Tailwind) ด้วย HSL คุณสร้าง scale ทั้งหมดได้โดยการขยับ lightness เป็นช่วง ๆ สม่ำเสมอ ในขณะที่ hue และ saturation คงที่:
:root {
--blue-50: hsl(210, 80%, 95%);
--blue-100: hsl(210, 80%, 87%);
--blue-200: hsl(210, 80%, 76%);
--blue-300: hsl(210, 80%, 65%);
--blue-400: hsl(210, 80%, 55%);
--blue-500: hsl(210, 80%, 50%); /* base */
--blue-600: hsl(210, 80%, 43%);
--blue-700: hsl(210, 80%, 36%);
--blue-800: hsl(210, 80%, 26%);
--blue-900: hsl(210, 80%, 16%);
}
สำหรับข้อมูลเชิงลึกเกี่ยวกับความสัมพันธ์ระหว่างรูปแบบสีต่าง ๆ คู่มือการแปลง HEX เป็น RGB ครอบคลุมภาพรวมทั้งหมดของรูปแบบสีใน CSS รวมถึงว่าแต่ละแบบเหมาะกับสถานการณ์ไหนครับ
Hover States, Theming และ Dark Mode
Hover และ focus states
HSL ทำให้การสร้าง hover state ง่ายมาก แทนที่จะกำหนดสีใหม่ทั้งหมด คุณแค่ขยับ lightness เท่านั้น:
.btn-primary {
background: hsl(210, 80%, 50%);
transition: background 0.2s ease;
}
.btn-primary:hover { background: hsl(210, 80%, 43%); }
.btn-primary:active { background: hsl(210, 80%, 36%); }
.btn-primary:focus-visible {
outline: 3px solid hsl(210, 80%, 70%);
}
ทุก state เชื่อมโยงกับสีหลักอย่างชัดเจน เพื่อนร่วมทีมที่อ่านโค้ดนี้จะเข้าใจความสัมพันธ์ระหว่าง state ต่าง ๆ ได้ทันทีครับ
Theming ด้วย HSL variables
HSL คือรากฐานของการทำ theming ใน CSS สมัยใหม่ ด้วยการเปิดให้ hue เป็น variable คุณสามารถให้ผู้ใช้หรือผู้ดูแลระบบเปลี่ยน color scheme ทั้งหมดของแอปได้ด้วยการเปลี่ยนตัวเลขแค่ตัวเดียว:
/* Default theme: blue */
:root {
--theme-hue: 210;
}
/* Green theme - just swap the hue */
[data-theme="green"] {
--theme-hue: 140;
}
/* Purple theme */
[data-theme="purple"] {
--theme-hue: 270;
}
/* All components use the same hue variable */
.button { background: hsl(var(--theme-hue), 75%, 50%); }
.link { color: hsl(var(--theme-hue), 75%, 40%); }
.badge { background: hsl(var(--theme-hue), 75%, 92%); color: hsl(var(--theme-hue), 75%, 25%); }
.focus-ring { outline-color: hsl(var(--theme-hue), 75%, 65%); }
Dark mode ด้วย HSL
Dark mode คือจุดที่ HSL โดดเด่นมากที่สุด แทนที่จะดูแล color palette สองชุดแยกกันทั้งหมด คุณแค่พลิก lightness ภายใน hue เดิม:
:root {
--bg: hsl(210, 20%, 98%); /* near-white background */
--text: hsl(210, 20%, 15%); /* near-black text */
--card: hsl(210, 20%, 93%); /* slightly darker card */
}
@media (prefers-color-scheme: dark) {
:root {
--bg: hsl(210, 20%, 10%); /* flip: near-black background */
--text: hsl(210, 20%, 90%); /* flip: near-white text */
--card: hsl(210, 20%, 15%); /* slightly lighter card in dark */
}
}
สังเกตว่า hue (210) และ saturation (20%) ไม่เปลี่ยนเลย มีแค่ lightness ที่พลิก ทำให้ dark mode รู้สึกเหมือนดีไซน์เดิมแต่กลับด้าน ซึ่งนั่นคือสิ่งที่ dark mode ที่ดีควรเป็นครับ
การรองรับของเบราว์เซอร์
HSL มีการรองรับจากเบราว์เซอร์ที่ดีเยี่ยมครับ ฟังก์ชัน
hsl()
พร้อมใช้งานมาตั้งแต่:
- Chrome 1 (2008)
- Firefox 1 (2004)
- Safari 3.1 (2008)
- Internet Explorer 9 (2011)
- Edge 12 (2015)
syntax สมัยใหม่แบบไม่ใช้ comma (
hsl(210 80% 50%)
) และ syntax แบบ slash-alpha (
hsl(210 80% 50% / 0.5)
) เป็นส่วนหนึ่งของ
CSS Color Level 4 specification
และรองรับในเบราว์เซอร์สมัยใหม่ทุกตัวตั้งแต่ปี 2023 ถ้าคุณยังต้องรองรับ IE11 (ซึ่งหายากแล้วในตอนนี้) ให้ใช้ syntax แบบ comma ไว้ก่อนครับ
hsl()
แบบใช้ comma ทำงานได้ในทุกเบราว์เซอร์ที่ผู้ใช้ของคุณน่าจะใช้อยู่ ส่วน syntax แบบ space-separated สมัยใหม่รองรับใน Chrome 90+, Firefox 89+ และ Safari 14.1+ ครอบคลุมการใช้งานเบราว์เซอร์ทั่วโลกมากกว่า 95%
คุณสามารถใช้ color picker เพื่อแปลงระหว่าง HSL, RGB และ HEX ได้เสมอ เมื่อต้องการเทียบค่าหรือส่งสีให้กับเครื่องมือที่รับได้แค่รูปแบบเดียวครับ
HSL vs OKLCH - ก้าวต่อไปคืออะไร?
ถ้าอยากไปไกลกว่า HSL OKLCH เป็นสิ่งที่ควรรู้จักครับ มันคือ color space แบบ perceptually uniform หมายความว่าการขยับค่า lightness หรือ chroma เป็นตัวเลขเท่ากันจะดูเหมือนเปลี่ยนเท่ากันจริง ๆ ต่อสายตามนุษย์ ซึ่ง HSL ไม่ได้รับประกันสิ่งนี้เสมอไป
ปัญหาของ HSL คือสองสีที่มีค่า lightness เท่ากันอาจดูสว่างต่างกันมาก เช่น
hsl(60, 100%, 50%)
(เหลือง) ดูสว่างกว่า
hsl(240, 100%, 50%)
(น้ำเงิน) มาก ทั้ง ๆ ที่ lightness 50% เท่ากัน OKLCH แก้ปัญหานี้ได้ครับ
/* HSL - same lightness, different perceived brightness */
color: hsl(60, 100%, 50%); /* yellow - looks very bright */
color: hsl(240, 100%, 50%); /* blue - looks much darker */
/* OKLCH - same lightness, actually looks the same to the eye */
color: oklch(0.75 0.18 90); /* yellow-ish */
color: oklch(0.75 0.18 260); /* blue-ish - genuinely similar perceived brightness */
OKLCH ยังรองรับ
wide-gamut colors
(สี P3 display) ที่เกินขอบเขต sRGB ที่ HSL จำกัดอยู่ด้วย การรองรับ
oklch()
ในเบราว์เซอร์แข็งแกร่งแล้วในปี 2024: Chrome 111+, Firefox 113+, Safari 15.4+
สำหรับโปรเจกต์ส่วนใหญ่ในตอนนี้ HSL คือจุดสมดุลที่ใช้งานได้จริง อ่านง่าย ดูแลรักษาง่าย รองรับทุกที่ และดีกว่า RGB มาก ส่วน OKLCH คือตัวเลือกที่ถูกต้องเมื่อคุณกำลังสร้าง design system ที่ต้องการ contrast ratio ที่แม่นยำทางคณิตศาสตร์ หรือต้องการรองรับจอแบบ wide-gamut ครับ
ถ้าคุณอยากสำรวจความสัมพันธ์ของสีแบบ visual ขณะสร้าง palette color explorer tool ช่วยให้คุณทดลองค่า HSL และดูว่าการหมุน hue, การเปลี่ยน saturation และการปรับ lightness ส่งผลยังไงแบบ real-time ครับ
เลือกสี HSL ได้อย่างแม่นยำโดยไม่ต้องเดา
color picker ของเราให้คุณปรับค่า hue, saturation และ lightness แบบ visual แล้ว copy ผลลัพธ์ HSL ไปใส่ใน CSS ได้เลย ไม่ต้องคำนวณเองครับ
ลองใช้ Color Picker →
ไม่จำเป็นต้องเขียนใหม่ทั้งหมดครับ แต่คุ้มค่าที่จะเริ่มใช้ HSL สำหรับการกำหนดสีใหม่ทุกครั้ง โดยเฉพาะเมื่อใช้ CSS custom properties ประโยชน์สูงสุดจะเห็นชัดเมื่อคุณกำลังสร้างหรือดูแล design system, สร้าง hover states หรือทำ dark mode การผสม RGB และ HSL ในโปรเจกต์เดียวกันถือว่าถูกต้องตาม CSS ทุกประการ เบราว์เซอร์รองรับทั้งคู่โดยไม่มีความแตกต่างด้านประสิทธิภาพครับ
ไม่มีความแตกต่างด้านประสิทธิภาพที่มีนัยสำคัญครับ เบราว์เซอร์แปลงรูปแบบสีทุกแบบใน CSS ไปเป็น representation ภายในตอน parse time ดังนั้นไม่ว่าคุณจะเขียน
hsl(207, 44%, 49%)
หรือ
rgb(70, 130, 180)
rendering engine ก็ถือว่าเหมือนกันทุกประการหลังจาก parse ขั้นตอนแรกนั้น การเลือกใช้อยู่ที่ประสบการณ์ของนักพัฒนาและความสะดวกในการดูแลรักษา ไม่ใช่ runtime performance ครับ
ได้ครับ และนี่คือหนึ่งในกรณีใช้งานที่แข็งแกร่งที่สุดของ HSL ใน JavaScript คุณสามารถเก็บ hue, saturation และ lightness เป็นตัวเลขแยกกัน แล้วสร้าง string ของสีแบบ dynamic:
element.style.color = `hsl(${hue}, ${saturation}%, ${lightness}%)`
ทำให้การทำ animation, การสลับ theme และการควบคุมสีแบบ interactive ง่ายกว่าการทำงานกับ RGB channel มาก เพราะถ้าใช้ RGB คุณต้องคำนวณแปลงค่าเพื่อให้ได้ผลลัพธ์เดียวกันครับ
HSL (hue, saturation, lightness) และ HSB/HSV (hue, saturation, brightness/value) เป็น color model ที่ต่างกัน แม้จะใช้แกน hue ร่วมกันก็ตาม ใน HSL ค่า lightness 50% ให้สีบริสุทธิ์ที่ saturated เต็มที่ ส่วนใน HSB ค่า brightness 100% ให้สีบริสุทธิ์ ทั้งสอง model ให้ผลลัพธ์ต่างกันสำหรับค่า saturation และ brightness/lightness เดียวกัน CSS ใช้ HSL โดยเฉพาะ ส่วน HSB/HSV พบบ่อยในเครื่องมือดีไซน์อย่าง Photoshop และ Figma แต่ไม่ใช่รูปแบบ CSS โดยตรงครับ
การแปลงจาก HEX เป็น HSL ต้องผ่านขั้นตอนกลางด้วย RGB ก่อนครับ นั่นคือแปลงคู่ HEX เป็นค่า RGB (0-255) ก่อน แล้ว normalize ให้อยู่ในช่วง 0-1 จากนั้นจึงใช้สูตรแปลง HSL ในทางปฏิบัติ นักพัฒนาส่วนใหญ่ใช้ color picker tool, เครื่องมือดีไซน์อย่าง Figma หรือ browser DevTools color picker ทำสิ่งนี้ได้ทันทีโดยไม่ต้องคำนวณเองครับ โดย DevTools ของเบราว์เซอร์ให้คุณคลิก color swatch แล้วสลับดูระหว่าง HEX, RGB และ HSL ได้เลย
ใช่ครับ OKLCH เชื่อถือได้มากกว่าสำหรับงาน accessibility เพราะเป็น perceptually uniform ซึ่งหมายความว่าการขยับค่า lightness เท่ากันจะสอดคล้องกับการเปลี่ยนแปลงความสว่างที่รับรู้ได้เท่ากัน ทำให้สร้าง color palette ที่ contrast ratio คาดเดาได้ข้ามหลาย hue ง่ายขึ้น ส่วน HSL นั้น yellow ที่ lightness 50% ดูสว่างกว่า blue ที่ lightness 50% มาก ซึ่งอาจทำให้เกิดปัญหา accessibility ที่ไม่คาดคิด สำหรับการทำ WCAG contrast compliance OKLCH ให้ผลลัพธ์ที่คาดเดาได้มากกว่าเมื่อสร้าง color scale ที่ accessible ครับ