คู่มือ CSS color-mix() Generator: ผสมสีในทุก Color Space ของ CSS
ทำความเข้าใจ CSS color-mix() และวิธีผสมสีสองสีใน sRGB, OKLab, OKLCH และอื่น ๆ พร้อม live preview และ CSS ที่ copy ใช้ได้ทันที
Table of Contents
ในอดีตการผสมสีสองสีใน CSS มักแปลว่าต้องพึ่ง preprocessor อย่าง Sass, ก๊อปปี้ค่า hex จาก design tool มาวาง manually หรือเขียน JavaScript utility เล็ก ๆ ไว้คำนวณสี hover state. สเปก CSS Color 5 ปิดจ๊อบนี้ด้วยฟังก์ชัน native เพียงตัวเดียว: color-mix() วันนี้เราเขียน color-mix(in oklab, #ff6347 50%, #4682b4) ลงใน stylesheet ได้เลย แล้วให้ browser เป็นค่าผสมสีให้ — ไม่ต้องมี build step, ไม่ต้องมี runtime, และไม่มีค่า hex ที่คัดลอกไว้หลายที่แล้วเพี้ยนจาก design tokens ของเรา
แต่ปัญหาคือ color-mix() มีรายละเอียดซ่อนอยู่เยอะกว่าที่คิด จะเลือก interpolation space ตัวไหน — srgb, oklab, oklch หรืออีกเก้าตัวที่สเปกรองรับ? ตัวเลข percentage ที่ใส่เนี่ยหมายความว่าอะไรจริง ๆ? ทำไมคู่สีเดียวกัน ผสมใน space หนึ่งแล้วออกมาหม่น แต่อีก space หนึ่งกลับสดใส? CSS color-mix() Generator ตอบคำถามพวกนี้แบบ interactive: เลือกสีสองสี, เลือกจาก 12 color spaces, ลาก slider แล้วดูผลลัพธ์อัปเดตสด ๆ พร้อม CSS ที่ copy ใช้ได้ทันทีด้านล่าง
ในคู่มือนี้เราจะไล่ดูว่า generator ทำงานยังไง, browser ทำอะไรบ้างตอน interpolate สี และ design patterns ที่ทำให้ color-mix() กลายเป็นหนึ่งใน modern CSS features ที่คุ้มที่สุดสำหรับงาน design system
ทำไมต้องใช้ CSS color-mix() Generator?
- Zero setup, zero dependencies. เครื่องมือทำงานใน browser ทั้งหมด ไม่ต้องสมัครสมาชิก ไม่ต้อง upload อะไร และค่าสีของคุณไม่เคยถูกส่งออกจากเครื่อง — 100% client-side
- ครบทั้ง 12 interpolation spaces ในที่เดียว. สเปก CSS Color 5 นิยาม srgb, srgb-linear, lab, oklab, xyz, xyz-d50, xyz-d65, hsl, hwb, lch, oklch และ display-p3 generator เปิดทุกตัวไว้ใน dropdown เดียว เทียบผลลัพธ์ side by side ได้เลยไม่ต้องเดา
- Live preview ก่อนเอาไปใช้จริง. แถบ swatch สามช่องแสดง Color 1, สีที่ผสมได้ และ Color 2 แบบ real-time — เห็นตรง ๆ ว่า browser จะ render อะไร รวมถึงความต่างที่ subtle ระหว่าง mix แบบ oklab กับ srgb จากคู่สีเดียวกัน
- Output พร้อม copy. CSS ที่ได้มาถูก syntax เป๊ะ ทั้ง casing และตำแหน่ง percentage วางแปะลง stylesheet หรือไฟล์ design token ได้ทันทีไม่ต้องแก้มือ
- รองรับ input หลายรูปแบบ. วางสีเป็น hex 3 หลัก (#f63), 6 หลัก (#ff6347) หรือ 8 หลักพร้อม alpha (#ff6347cc) ก็ได้ หรือจะใช้ native color picker เลือกจากจอก็ได้ โดยค่า alpha จะถูกเก็บไว้ผ่าน mix ด้วยกลไก premultiplied alpha ของสเปก
- เป็นทั้งเครื่องมือและห้องทดลอง. เพราะสลับ space ได้ทันที generator จึงใช้สร้าง intuition เรื่อง perceptual color spaces ไปในตัว — วิธีที่เร็วที่สุดในการเข้าใจว่า ทำไม OKLab ถึงถูกสร้างขึ้นมา
คุณสมบัติเด่น
| คุณสมบัติ | รายละเอียด |
|---|---|
| ช่องกรอกสี 2 สี | ช่อง hex + native color picker รองรับ hex 3, 6 และ 8 หลัก |
| 12 color spaces | ครบทุก interpolation space ที่ CSS Color 5 นิยามไว้ |
| Percentage slider | คุมสัดส่วนของ Color 1 ตั้งแต่ 0% ถึง 100% ค่าเริ่มต้นเป็น 50/50 |
| Live preview 3 ช่อง | Color 1, ผลลัพธ์ และ Color 2 อัปเดตทันทีที่ปรับค่า |
| CSS พร้อม copy | ได้ syntax ตรงตัวอย่าง color-mix(in oklab, #FF6347 50%, #4682B4) |
| 100% client-side | คำนวณทุกอย่างใน browser ไม่มีการ upload ข้อมูล |
มีสองรายละเอียดที่น่าคัดมาเน้น อย่างแรก slider ทำงานตามโมเดลของสเปก: ค่าบน slider คือสัดส่วนของ Color 1 ส่วนที่เหลือถือว่าเป็น Color 2 โดยปริยาย — 50% คือผสมกันเท่า ๆ กัน, 100% คือ Color 1 ล้วน และ 0% กลายเป็น Color 2 ล้วน อย่างที่สองเครื่องมือ validate ค่า hex ที่พิมพ์เข้ามาแบบ real-time และ fallback อย่างระมัดระวัง ค่าที่พิมพ์ครึ่ง ๆ กลาง ๆ จะไม่ทำให้ preview พัง
ส่วน browser support ของ color-mix() เองในปี 2026 นับว่ากว้างมาก: Chrome 111+, Safari 16.2+ และ Firefox 113+ รองรับ native ครบ ซึ่งครอบคลุม evergreen browsers เกือบทั้งหมดแล้ว
วิธีใช้งาน
- เปิด CSS color-mix() Generator — เครื่องมือโหลดพร้อมคู่สี default ที่เหมาะสมคือ tomato #ff6347 กับ steel blue #4682b4
- ตั้งค่าสีตั้งต้นสองสีผ่านช่อง hex หรือ native color picker ใช้ได้ทั้งแบบ 6 หลักและ shorthand ส่วน hex 8 หลักจะเก็บ alpha ไว้ด้วย
- เลือก interpolation space จาก dropdown เริ่มจาก oklab สำหรับงานทั่วไป — ที่เครื่องมือตั้งเป็น default ไว้มีเหตุผลของมัน
- ลาก percentage slider เพื่อคุมว่า Color 1 เข้า mix มากแค่ไหน แล้วดู swatch ตรงกลางเปลี่ยนสด ๆ ตามมือ
- กดปุ่ม Copy ข้างช่อง CSS output แล้วเอา declaration color-mix() ไปวางใน stylesheet, ไฟล์ token หรือ CSS custom property ได้เลย
ทำความเข้าใจ Color Interpolation Spaces
แนวคิดสำคัญที่สุดของ color-mix() คือ "สีที่อยู่กึ่งกลางระหว่างแดงกับน้ำเงิน" เป็นคำถามที่ ยังไม่สมบูรณ์ จนกว่าจะบอกว่าใช้ color space ไหน แต่ละ space interpolate ไปตามแกนต่างกัน จุดกึ่งกลางจึงตกอยู่คนละที่
srgb และ srgb-linear. space srgb interpolate ช่องสัญญาณ RGB แบบ gamma-encoded ตามที่เราคุ้นเคย ทำงานได้ทุกที่และเร็ว แต่ไม่ perceptually uniform: จุดกึ่งกลางมักสูญเสีย saturation และมืดกว่าที่ตาคาด — อาการ "ตรงกลางหม่น" คลาสสิกที่เจอใน gradient แบบ RGB ระหว่างสีจัดที่ตรงข้ามกัน ส่วน srgb-linear interpolate ในพิกัด linear-light ให้การเปลี่ยน luminance ราบรื่นเชิงฟิสิกส์ เหมาะกว่าเมื่อผลลัพธ์จะเอาไปใช้กับเอฟเฟกต์ opacity หรือ blend
hsl, hwb, lch. กลุ่ม cylindrical spaces นี้ interpolate ค่า hue เป็นมุม ทำให้ความสดคงอยู่ตลอด mix — แต่ก็มาพร้อม hue-shift artifact: ผสมเหลืองกับน้ำเงินใน HSL อาจวิ่งผ่านเขียวทั้งที่ดีไซน์ของเราไม่ได้อยากได้เขียวมา ส่วน LCH ดีขึ้นเรื่อง lightness uniformity แต่ยัง over-saturate จุดกึ่งกลางในบางคู่ hue อยู่ ได้สีที่ chroma สูงกว่าปลายทั้งสองข้าง
oklab และ oklch. OKLab ถูกออกแบบมาให้ perceptually uniform: ระยะทางเชิงตัวเลขที่เท่ากัน ≈ การเปลี่ยนที่ตารับรู้เท่ากัน oklab ผสม lightness กับสีในลักษณะที่จุดกึ่งกลางดู "อยู่ระหว่าง" แบบธรรมชาติ — ไม่หม่นเป็นเทา ไม่นีออนเกิน ส่วน oklch เติม hue angle เข้าไปบนฐานเดียวกัน ทำให้ mix เรียบรับกับการหมุน hue สำหรับงาน UI ทั่วไป — hover state, tint, shade, border — oklab คือ default ที่ practical ที่สุด และนั่นคือเหตุผลที่เครื่องมือเลือกไว้ล่วงหน้า
xyz, xyz-d50, xyz-d65, display-p3. ตระกูล XYZ เป็น tristimulus spaces ที่ device-independent เกี่ยวข้องมากเมื่อต้องการ mix แบบ color-management แม่นยำสำหรับ pipeline งานพิมพ์หรือ ICC workflow (d50 กับ d65 คือ white point ต่างกัน) ส่วน display-p3 interpolate ภายใน gamut P3 เหมาะกับงาน wide-gamut ที่ต้องการผลลัพธ์ที่ยังแสดงได้บนจอสมัยใหม่ แทนที่จะถูก clamp กลับมาที่ sRGB
เกมจบด้วยกลไกสองตัว Premultiplied alpha: ถ้า input มี alpha สเปกจะ premultiply ช่องสีด้วย alpha ก่อน interpolate แล้ว un-premultiplied ภายหลัง ป้องกันสีโปร่งใส "แซบ" ความสว่างที่ไม่พึงประสงค์เข้าไปในผลลัพธ์ ส่วน percentage: p1% หมายถึงดึงผลลัพธ์จาก Color 2 ไปทาง Color 1 ตามเส้น interpolation เป็นระยะ p1% ถ้าใส่ทั้งสองฝั่งแล้วรวมกันเกิน 100% ตัวเลขจะถูก normalize — นี่คือรายละเอียดที่คนเขียน color-mix(in oklab, red 60%, blue 60%) มักเจอแล้วงง
Use Cases ในทางปฏิบัติ
สร้าง tint/shade scale จาก token ตัวเดียว
แทนที่จะ hardcode hex สิบเอ็ดค่าต่อหนึ่งสี brand ให้นิยามสีหลักแล้ว derive ทั้ง ramp: --brand-600: color-mix(in oklab, var(--brand) 80%, black) ได้ shade ส่วนผสมกับ white ในสัดส่วนที่เพิ่มขึ้นได้ tint ทั้ง scale — มี source of truth เดียว และการ re-theme ทั้งเว็บกลายเป็นการแก้ตัวแปรตัวเดียว
Hover, pressed และ focus state โดยไม่ต้องมี preprocessor
Pattern มาตรฐานคือ background: color-mix(in oklab, var(--accent) 85%, black) สำหรับ hover และ mix กับ white สำหรับ state โปร่งแบบ disabled นี่คือสิ่งที่ lighten() กับ darken() ของ Sass พยายามจะเป็นมาตลอด — แต่คำนวณโดย browser, อยู่ใน space ที่ perceptually even และ sync กับ token ต้นทางเสมอ
ปรับสี dark mode ให้จบในบรรทัดเดียว
ธีมมืดมักต้องการเวอร์ชันสี brand ที่จางลงและยกความสว่างขึ้นเล็กน้อย color-mix(in oklab, var(--brand) 70%, #1c1c22) ดึง accent จัด ๆ เข้าหาพื้นหลังเข้ม และ declaration เดียวกันใช้ได้กับทุก accent เพราะอ้างจาก token ไม่ใช่ค่า literal เมื่อใช้คู่กับรูปแบบ light-dark() จะได้ dual-theme palette เต็มชุดด้วย declaration ไม่กี่บรรทัด
Focus ring และ contrast tuning ที่เข้าถึงได้
เมื่อสี accent ใกล้กับพื้นหลังเกินไป การ mix เข้าหา black หรือ white ใน oklab จะขยับ lightness — และพ่วงจากนั้น contrast — เป็น step ที่คุมได้ ลอง generate mix หลาย ๆ ตัวในเครื่องมือ แล้วเอาคู่ที่ดีที่สุดไปเช็กต่อด้วย Color Contrast Checker เพื่อยืนยันว่าผ่านเกณฑ์ WCAG ก่อน ship
Best Practices
- ตั้ง oklab เป็น default ของ UI state colors. เลือก space อื่นอย่างมีเจตนา: oklch เมื่อต้องการหมุน hue แบบคุมได้, srgb เมื่อต้อง match gradient เดิม, display-p3 สำหรับ asset แบบ wide-gamut
- Mix กับ currentColor เพื่อทำ theming. color-mix(in oklab, currentColor 70%, transparent) สร้าง variant โปร่งใสที่ตามสี text ที่ inherit มาอัตโนมัติ — เหมาะกับ icon, divider และ border บาง ๆ
- ห่อ mix เก็บไว้ใน custom property. การ wrap ฟังก์ชันเป็น --hover: color-mix(...) ไว้ที่ชั้น token ทำให้ component สะอาดและตรวจสอบการ derive ได้จากที่เดียว
- ทดสอบปลายทั้งสองข้างของ slider. เช็กค่า 0% กับ 100% และค่ากลาง — space ที่ดูดีที่ 50% อาจพฤติกรรมแปลกใกล้ขอบเขต โดยเฉพาะเมื่อมี alpha เกี่ยวข้อง
- ใช้ relative color syntax สำหรับแปลงค่าเชิงช่องสัญญาณ. จับคู่ color-mix() กับ relative color (keyword from) เมื่อต้องปรับระดับช่องต่าง ๆ เช่น oklch(from var(--brand) calc(l + 0.1) c h)
- ตรวจ contrast อย่าเดา. blend ที่ even ทาง perception เปลี่ยน lightness เป็นหน่วย perceptual ไม่ใช่ contrast ratio — mix ที่มี text ด้านบนต้องเช็กกับเกณฑ์ขั้นต่ำของ WCAG เสมอ
สรุปและชวนใช้
color-mix() ลบเหตุผลประจำวันข้อสุดท้ายที่ทำให้เรายังต้องแบก preprocessor หรือ color-math library ไว้ใน stack เมื่อ tint, shade, hover state และการปรับธีม derive จาก token ไม่กี่ตัวทั้งหมด การ re-theme กลายเป็นการแก้ตัวแปรตัวเดียว และ palette ของคุณก็เลิกเพี้ยนไปเอง
เปิด CSS color-mix() Generator ใส่สีสองสีของคุณลงไป แล้วลองเทียบ srgb กับ oklab บนคู่สีเดียวกัน — ความต่างที่เห็นคือวิธีเร็วที่สุดในการเข้าใจว่า perceptual interpolation ซื้ออะไรให้คุณ ทุกอย่างทำงาน local ใน browser ของคุณ และ output พร้อมวางใช้เสมอ
ขอให้สนุกกับการผสมสี!