กลับไปหน้าบทความ
#Dark Mode#CSS#Web Development#prefers-color-scheme#UX

ทำ Dark Mode แบบไม่พังด้วย CSS prefers-color-scheme

การทำ Dark Mode ที่ดีไม่ใช่การกลับสีทั้งหน้าแบบรวดเดียว แต่ต้องเริ่มจากระบบสีที่ออกแบบมาอย่างเป็นระเบียบด้วย CSS Variables ก่อน แล้วจึงใช้ prefers-color-scheme และการ override ของผู้ใช้ให้ทำงานร่วมกันอย่างถูกต้อง

9 กุมภาพันธ์ 2569อ่านประมาณ 2 นาที

แชร์บทความ

ทำ Dark Mode แบบไม่พังด้วย CSS prefers-color-scheme

ทำ Dark Mode แบบไม่พังด้วย CSS prefers-color-scheme

Dark Mode กลายเป็นมาตรฐานสำคัญของเว็บสมัยใหม่ แต่สิ่งที่หลายทีมพลาดคือการทำแบบเร่งรีบด้วยการ “กลับสีทั้งหน้า” ในครั้งเดียว ผลที่ตามมาคือรูปภาพเพี้ยน ปุ่มอ่านยาก ฟอร์มดูแปลก และคอนทราสต์ไม่ผ่านมาตรฐานการเข้าถึง

แนวทางที่ถูกต้องและดูเป็นมืออาชีพมากกว่าคือ การสร้างระบบสีด้วย CSS Variables หรือที่หลายคนเรียกว่า design tokens ก่อน จากนั้นจึงใช้ prefers-color-scheme เพื่อให้เว็บเลือกธีมตามระบบปฏิบัติการโดยอัตโนมัติ และเปิดทางให้ผู้ใช้สามารถเลือกธีมเองได้ในภายหลัง

ทำไมการกลับสีทั้งหน้าจึงทำให้เว็บพัง

การกลับสีแบบตรงไปตรงมาอาจดูเหมือนง่าย แต่ในทางปฏิบัติกลับสร้างปัญหาหลายด้าน เช่น

  • รูปภาพและไอคอนบางส่วนสีเพี้ยน
  • ปุ่มหรือข้อความมีคอนทราสต์ต่ำจนอ่านยาก
  • ฟอร์มอย่าง input, select, textarea หลุดธีม
  • ส่วนประกอบบางจุดดูไม่สัมพันธ์กัน เช่น การ์ดสว่างเกินไปแต่ตัวอักษรมืดเกินไป

Dark Mode ที่ดีจึงไม่ใช่แค่ “ทำให้พื้นหลังเป็นสีดำ” แต่ต้องออกแบบความสัมพันธ์ของสีทั้งหมดใหม่ให้เหมาะกับการอ่าน การใช้งาน และความสบายตา

เริ่มจากระบบสีด้วย CSS Variables

หัวใจสำคัญคือการกำหนดสีทั้งหมดผ่านตัวแปร CSS แทนการใส่ค่าสีตรง ๆ กระจายไปตามแต่ละ class วิธีนี้ช่วยให้เราสลับธีมได้ทั้งระบบโดยแก้เพียงค่าของตัวแปร

แนวคิดที่ควรใช้คือแยกสีเป็นคู่ ๆ เช่น

  • bg และ fg สำหรับพื้นหลังกับข้อความหลัก
  • card และ cardText สำหรับพื้นผิวของการ์ดกับข้อความในการ์ด
  • สีลิงก์ สีเส้นขอบ และสีเน้นต่าง ๆ

โครงสร้างที่แนะนำคือเริ่มจากค่าเริ่มต้นแบบ Light Mode ใน :root ก่อน เพราะรองรับได้กว้างและปลอดภัยที่สุด จากนั้นจึงเพิ่ม @media (prefers-color-scheme: dark) เพื่อสลับค่าตัวแปรสำหรับ Dark Mode

แทนที่จะเปลี่ยนสีทีละปุ่มหรือทีละหน้า เราเพียงสลับค่าของ variables ทั้งชุด ระบบก็จะเปลี่ยนธีมอย่างเป็นระเบียบและดูแลง่ายกว่าในระยะยาว

รองรับ 3 สถานะให้ครบ: Light, Dark และ User Override

ระบบธีมที่ดีควรรองรับอย่างน้อย 3 สถานะ ได้แก่

  1. Light Mode ตามค่าเริ่มต้น
  2. Dark Mode ตามค่าระบบด้วย prefers-color-scheme
  3. User Override หรือกรณีที่ผู้ใช้เลือกธีมเอง

แนวทางที่นิยมคือ หากผู้ใช้ยังไม่เคยเลือกธีม ให้เว็บไซต์อิงตามค่าระบบปฏิบัติการก่อน แต่ถ้าผู้ใช้กดเลือก Light หรือ Dark ด้วยตนเองแล้ว ให้ใส่ class เช่น .theme-light หรือ .theme-dark ไว้บน html และบันทึกค่าไว้ใน localStorage

จุดสำคัญมากคือ CSS ของการ override ต้องมีลำดับหรือ specificity ที่ชนะ media query ไม่เช่นนั้นบางหน้าจะย้อนกลับไปตามธีมของระบบแบบคาดไม่ถึง วิธีง่ายที่สุดคือเขียน .theme-dark และ .theme-light ไว้หลังส่วน @media

อย่าลืม color-scheme ให้เบราว์เซอร์ช่วยงาน

อีกเทคนิคที่ช่วยลดงานจุกจิกได้มากคือกำหนด

html {
  color-scheme: light dark;
}

เมื่อใส่ค่านี้ เบราว์เซอร์จะช่วยปรับองค์ประกอบ native UI บางส่วนให้เข้ากับธีมมากขึ้น เช่น

  • input
  • select
  • textarea
  • scrollbar

ผลคือเราต้องเสียเวลาแก้รายละเอียดเล็ก ๆ น้อยลง และหน้าตาโดยรวมจะกลมกลืนกับธีมมากขึ้นโดยอัตโนมัติ

รูปภาพและไอคอนคือจุดที่คนมักพลาด

แม้ระบบสีจะดีแค่ไหน แต่ถ้ารูปภาพหรือไอคอนไม่รองรับธีม เว็บก็ยังดูไม่สมบูรณ์ โดยเฉพาะไอคอนแบบ SVG ควรใช้ currentColor หรือผูกเข้ากับตัวแปรสี เพื่อให้สีของไอคอนเปลี่ยนตามธีมได้ทันทีโดยไม่ต้องเตรียมไฟล์สองชุด

สำหรับภาพพื้นหลังหรือกราเดียนต์ ควรตรวจสอบให้แน่ใจว่าคอนทราสต์ยังเพียงพอในทุกโหมด เพราะหลายครั้งพื้นหลังที่สวยใน Light Mode อาจอ่านยากมากเมื่อเปลี่ยนเป็น Dark Mode

คอนทราสต์ที่ดีทำให้ Dark Mode ใช้งานได้จริง

Dark Mode ที่ดูดีไม่ได้หมายถึงดำสนิทกับขาวสนิทเสมอไป ในทางกลับกัน งานออกแบบที่ดูพรีเมียมมักเลือกใช้

  • พื้นหลังเป็น near-black แทนดำล้วน
  • ตัวอักษรเป็น off-white แทนขาวล้วน

วิธีนี้ช่วยให้สบายตาและลดความแข็งของภาพรวมได้มาก นอกจากนี้ควรให้ความสำคัญกับข้อความขนาดเล็กเป็นพิเศษ เพราะเป็นจุดที่คอนทราสต์ต่ำแล้วอ่านยากที่สุด หากเป็นฟอนต์เล็กหรือบางมาก ควรหลีกเลี่ยงสีเทาอ่อนบนพื้นหลังดำสนิท

วิธีทดสอบ Dark Mode แบบมืออาชีพ

การทำธีมให้ครบไม่จบที่การเขียน CSS แต่ต้องทดสอบอย่างรอบด้านด้วย โดยควรเช็กอย่างน้อยดังนี้

  1. ทดสอบทั้ง 3 โหมด: ระบบเป็น Light, ระบบเป็น Dark และโหมดที่ผู้ใช้ override เอง
  2. ตรวจสอบฟอร์มทั้งหมด เช่น input, placeholder, autofill, และ focus ring เพราะมักหลุดธีมบ่อย
  3. เช็กภาพพื้นหลังและกราเดียนต์ว่าไม่ทำให้ข้อความจมหรือคอนทราสต์หาย
  4. เปิดใช้งาน forced colors หรือ high contrast บน Windows เพื่อดูความเข้ากันได้ด้านการเข้าถึง
  5. บนอุปกรณ์ Safari/iOS ให้ดู safe-area, สี address bar และสี selection ของข้อความเพิ่มเติม

หากต้องการทำงานเร็วขึ้น Chrome และ Edge DevTools สามารถ emulate prefers-color-scheme ได้ ทำให้สลับ Light/Dark ได้ทันทีโดยไม่ต้องเปลี่ยนธีมทั้งเครื่อง

แนวคิดที่ช่วยให้โค้ดอ่านง่ายและดูแลง่าย

โครงสร้างที่ดีควรเรียบง่ายและชัดเจน ดังนี้

  • กำหนดค่าเริ่มต้นแบบ Light ใน :root
  • เพิ่ม Dark Mode ผ่าน @media (prefers-color-scheme: dark)
  • เพิ่ม .theme-light และ .theme-dark สำหรับการ override
  • จัดกลุ่มตัวแปรสีตามหน้าที่ ไม่กระจายแบบไร้ระบบ

เมื่อทำตามแนวทางนี้ ทีมจะสามารถขยายระบบได้ง่ายขึ้น เช่น เพิ่มธีมใหม่ ปรับ branding หรือรีแฟกเตอร์หน้าเดิมโดยไม่กระทบทั้งระบบ

สรุป

การทำ Dark Mode ให้ไม่พัง เริ่มจากการออกแบบระบบสีด้วย CSS Variables ก่อน แล้วค่อยใช้ prefers-color-scheme เพื่อสลับธีมตามระบบปฏิบัติการ จากนั้นเสริมความยืดหยุ่นด้วยการให้ผู้ใช้ override ธีมเองได้

สิ่งสำคัญคืออย่าลืมเรื่อง color-scheme, การรองรับฟอร์ม ไอคอน รูปภาพ คอนทราสต์ และการทดสอบในหลายสภาพแวดล้อม หากวางโครงสร้างตั้งแต่ต้นอย่างถูกต้อง Dark Mode จะไม่ใช่งานแก้ปัญหาเฉพาะหน้า แต่จะกลายเป็นระบบที่สวย ใช้งานง่าย และดูแลต่อได้ในระยะยาว