เลิกแยกไฟล์ CSS! ทำไม Dark Mode ควรใช้ Semantic Tokens แทนการเขียนโค้ดซ้ำ
เจาะลึกปัญหาการแยกไฟล์ Dark Mode ที่ทำให้โปรเจกต์บำรุงรักษายาก พร้อมแนวทางแก้ด้วยการใช้ Semantic Tokens และโครงสร้างสถาปัตยกรรม CSS ที่ยั่งยืน

ภาพประกอบจากคลังภาพสต็อก ไม่ใช่ภาพจากเหตุการณ์จริง
- การแยกไฟล์ CSS สำหรับ Dark Mode เดี่ยวๆ ทำให้โค้ดซ้ำซ้อนและดูแลรักษายากเมื่อแอปพลิเคชันโตขึ้น
- การใช้ Semantic Tokens ช่วยให้คอมโพเนนต์ไม่ต้องรับรู้ว่าธีมไหนกำลังทำงานอยู่
- การเปลี่ยนธีมทำได้อย่างง่ายดายผ่าน Attribute เช่น data-theme บนแท็ก html
- ควรสคริปต์ขนาดเล็กในส่วนหัวของเอกสารเพื่อป้องกันปัญหาแฟลชธีมผิดพลาดตอนโหลดหน้าเว็บ
การพัฒนาโหมดมืดหรือ Dark Mode มักจะเริ่มต้นด้วยแนวคิดที่ดูเรียบง่ายในตอนแรก นั่นคือการสร้างไฟล์สไตล์ชีตแยกออกมาเป็นสองไฟล์ เช่น styles.css สำหรับธีมสว่าง และ dark.css สำหรับธีมมืด ซึ่งสำหรับหน้าอินเทอร์เฟซขนาดเล็ก วิธีนี้อาจดูสมเหตุสมผลและไม่มีปัญหาอะไรในระยะสั้น
อย่างไรก็ตาม เมื่อแอปพลิเคชันเติบโตขึ้น ไฟล์ทั้งสองเริ่มทำตัวเหมือนกับการจำลอง UI ชุดเดียวกันแยกออกจากกันเป็นสองชุด ทำให้กฎในไฟล์ dark.css ถูกหลงลืมได้ง่าย และทุกครั้งที่มีการปรับปรุงหน้าจอหลัก นักพัฒนาจำเป็นต้องคอยเขียนโค้ดทับหรือ override ตามในไฟล์โหมดมืดเสมอ ส่งผลให้การทำ Dark Mode มีต้นทุนที่สูงขึ้นเนื่องจากการออกแบบธีมถูกฝังไว้ระดับคอมโพเนนต์
การแยกไฟล์ CSS สำหรับธีมเป็นสองชุดตั้งแต่ต้นมักเป็นกับดักที่นักพัฒนาหลายคนตกลงไป เพราะคิดว่าจะช่วยให้จัดการง่าย แต่ในความเป็นจริงมันสร้างภาระทางเทคนิค (Technical Debt) มหาศาล เนื่องจากการซิงโครไนซ์สถานะต่างๆ ระหว่างสองไฟล์เมื่อระบบใหญ่ขึ้นกลายเป็นเรื่องที่ผิดพลาดได้ง่ายและใช้เวลาดูแลรักษามาก แนวคิดเรื่อง Token จึงเข้ามาแก้ปัญหานี้โดยการแยกโครงสร้าง UI ออกจากชุดข้อมูลสี
แนวทางที่ดีกว่าคือการเขียนคอมโพเนนต์โดยใช้ Semantic Tokens แทนที่จะใช้ค่าสีแบบฮาร์ดโค้ด โดยตัวคอมโพเนนต์จะสนใจแค่บทบาทเชิงความหมายของค่าต่างๆ เท่านั้น เช่น ใช้ตัวแปร --color-surface สำหรับการ์ด หน้าต่างอินพุต และพื้นผิวอื่นๆ โดยที่ธีมจะเป็นตัวกำหนดเองว่าค่าเหล่านั้นควรแสดงผลเป็นสีอะไรในแต่ละโหมด

ความแตกต่างทางสถาปัตยกรรมนี้ชัดเจนมาก หากเปรียบเทียบโครงสร้างแบบเก่าที่ต้องแยก CSS ของการ์ด ปุ่ม และอินพุต ออกเป็นแสงและมืด กับโครงสร้างแบบใหม่ที่มีคอมโพเนนต์การ์ด ปุ่ม และอินพุตอย่างละหนึ่งชุด แต่สลับค่า Token มูลค่าแสงและมืดแทน ดังโครงสร้างตัวอย่าง:
- โครงสร้างเดิม: Light card CSS, Dark card CSS, Light button CSS, Dark button CSS, Light input CSS, Dark input CSS
- โครงสร้างใหม่: One card component, One button component, One input component ร่วมกับ Light token values และ Dark token values
สำหรับการนำธีมไปใช้งานจริง วิธีที่ปฏิบัติได้จริงคือการใช้ Data Attribute บนแท็ก HTML เช่น <html data-theme="dark"> แล้วให้ CSS จัดการขอบเขตของค่า Token ตามชุดข้อมูลนั้น ซึ่งสามารถสลับโหมดผ่านจาวาสคริปต์ได้อย่างง่ายดาย เช่น การกำหนดค่า document.documentElement.dataset.theme = "dark" หรือลบ Attribute ทิ้งเพื่อให้ระบบปฏิบัติการเป็นตัวจัดการค่าเริ่มต้น
ที่มา: Dev.to
พบข้อมูลผิดพลาดในบทความนี้? แจ้งปัญหาบทความนี้
ความคิดเห็น
แสดงความคิดเห็น