ประสบการณ์เปลี่ยนเว็บ Wongnai ให้กลายเป็น Dark Mode

Pipe Kittapon
Life@LINE MAN Wongnai
7 min readJan 27, 2023

--

Dark Mode สำหรับเราๆ ที่เป็น Software Engineer หรือใครก็ตามที่ต้องอยู่หน้าจอเป็นเวลานานๆ น่าจะคุ้นเคยกันดีอยู่แล้ว สำหรับ Web Developer ก็เช่นกันครับ คิดว่าหลายๆ คนคงอยากให้เว็บที่ตัวเองทำมีฟีเจอร์ที่ทำให้รู้สึกเท่นิดๆ นี้ให้ใช้งานได้เหมือนกัน

สวัสดีครับ ผมไปร์สจากทีม Frontend, LINE MAN Wongnai วันนี้จะมาเล่าประสบการณ์การทำ Dark Mode ให้กับเว็บ Wongnai เมื่อช่วงกลางปี 2022 ทั้งปัญหาที่เจอ ตลอดจนวิธีการแก้ปัญหาที่ผมเอามาใช้ครับ

แน่นอนว่าถ้าไปค้นหาน่าจะเจอบทความเกี่ยวกับการทำ Dark Mode จำนวนมาก ไม่ว่าจะเป็นวิธีการหรือ tool ที่นำมาใช้ ดังนั้นในบทความนี้จะขอเล่าในมุมของการ migrate และ implement กับ legacy code ของ Wongnai project ครับ

ต้องขอเล่าย้อนไปก่อนว่า เมื่อประมาณ 2 ปีก่อน Wongnai ได้มีการทำ design system (DS2.0) ใหม่ขึ้นมาครับ โดยตัว DS2.0 นี้ได้มีการเตรียม palette และ theme ต่างๆ ไว้เพื่อให้รองรับ Dark Mode ตั้งแต่แรกเลย

ทำไมผ่านมา 2 ปี กว่าจะใช้ Dark Mode ได้?

เหตุผลแรกสุดคือ Wongnai web เป็นโปรเจกต์ที่ใหญ่มาก มีจำนวนหน้า และ legacy code ที่เยอะมาก รวมถึง code style ข้างในที่มีทั้งตั้งแต่ยุคบุกเบิกจนมาถึงปัจจุบัน ทำให้ถ้าจะทำให้ Dark Mode ใช้งานได้ต้องใช้ resource ทั้งคนและเวลาจำนวนมากครับ

แต่ว่าเราไม่ได้มี resource ให้ใช้เยอะขนาดนั้น เพราะถึง Dark Mode จะทำให้เว็บดูดี ดูเท่ขึ้น แต่หากพูดกันในมุม Business value มันกลับไม่ได้มีมากขนาดนั้น (หากไม่มี requirement เข้ามา) ทำให้ priority ในการทำแทบไม่มีเลย

ดังนั้นสิ่งที่เราทำตั้งแต่มี DS2.0 มา จึงทำแคนำสีใหม่ไปใช้ ,สร้าง component ขึ้นมาใหม่ และไล่ migrate หน้าสำคัญๆ ที่มีคนใช้เยอะๆ ให้กลายเป็น DS2.0 เท่านั้นครับ

ก่อนจะเริ่ม ขอเกริ่นก่อนว่า LINE MAN Wongnai ใช้ React + Styled-Component เป็นหลัก ดังนั้นวิธีการที่ใช้และปัญหาที่เจอจะเกี่ยวกับ 2 อย่างนี้เป็นหลักครับ

เอาล่ะ มาเข้าประเด็นสำคัญกัน

Implementation & Issue

หัวใจของการทำ Dark mode จริงๆ นั้นง่ายมากเลยครับ

“สี”

แค่นั้นเลยครับ ขอแค่มีสีใน light mode และ dark mode พร้อมก็เพียงพอแล้ว (ส่วนวิธี implement ก็มีหลากหลาย) ซึ่งอย่างที่เกริ่นไว้ตัว DS2.0 ก็รองรับจุดนี้ ผมจึงไม่มีปัญหาเรื่องการเลือกสีที่จะเอามาใช้ครับ

จนถึงเมื่อประมาณปลายปีที่แล้ว ผมได้เริ่มทำ Wongnai Dark Mode โดยมี goal แบบเรียบง่าย คือควรจะ implement ด้วยท่าที่ง่าย take effort, take time ไม่เยอะ เพื่อจะประหยัด resource

แต่ระหว่างทางก่อนที่ feature นี้จะถูกนำขึ้น production ก็ใช่ว่าจะเป็นไปอย่างราบรื่น เพราะขณะที่นั่งคิดหาวิธีแก้ไปเรื่อยๆ ก็เจอปัญหาที่มากขึ้นเรื่อยๆ เช่นกันครับ

Internal Color

อย่างที่เกริ่นไว้ข้างต้น Wongnai web ถูกขึ้นโปรเจคมาเกินกว่า 5 ปีแล้ว จนถึงตอนนี้ก็มีขนาดที่ใหญ่มากๆ ซึ่ง style ที่ถูกนำมาใช้ก็มีทั้ง css, scss และ styled-component

ปัญหาเกี่ยวกับสีอย่างแรกคือการทำให้ทั้ง css, scss และ styled-component สามารถดึงแหล่งสีเดียวกันมาใช้ได้

ปัญหานี้ สามารถ solve ได้ด้วยท่าที่หลายๆ blog แนะนำให้ใช้ เพียงแค่ทำ css variable ที่เป็น native css แปะไว้ที่ root (จะมีสีทั้งหมดที่ต้องใช้) ตอนที่เรียกใช้เพียงใส่สีด้วย variable ของแต่ละสีก็จะสามารถใช้สีนั้นๆ ได้เลยครับ

:root {
var(--gray-100): gray;
var(--red-500): red;
}

// global-style.css

ปัญหาอย่างที่ 2 คือสีที่ใช้ครับ สีใน Wongnai ที่ขึ้นโปรเจคมานานมีคละกันทั้งสีของ DS0 (ช่วงก่อนมี design system), DS1.0, DS2.0 และรวมถึงสีที่นำมาใช้โดยไม่ผ่าน design system ซึ่งสีเหล่านี้เกือบทั้งหมดจะไม่ตรงกับสีที่มีใน DS2.0 ใหม่ทำให้จุดที่ยังใช้สีเหล่านี้อยู่จะไม่สามารถใช้กับ Dark Mode ได้

โดยปัญหานี้จะขอแบ่งเป็น 3 ปัญหาย่อยครับ

1. การ map สีจาก DS1.0 ไป DS2.0

  • ผมจะใช้ algorithm หนึ่งที่ชื่อว่า CIEDE2000 ที่จะใช้สำหรับหาความแตกต่างของสี โดยหลักการคร่าวๆ คือจะนำค่า “H (hue)” , “C (chroma)”, “L (lighten)” ของสีที่จะเปรียบเทียบกันมาหาความแตกต่าง และได้ผลลัพธ์ออกมาในรูปของตัวเลข ยิ่งค่าใกล้ 0 เท่าไรก็แปลว่าสีมีความใกล้เคียงกันเท่านั้น
|#000000 - #ffffff| ≈ 100
|#7f7f7f - #808080| 0.392
  • ในส่วนนี้ผมจะเอาสีต่างๆ มาเทียบกับสีของ DS2.0 แล้วใช้ runkit ของ lib color-difference ตัวนี้ เพื่อ หาสีที่ใกล้เคียงที่สุด ด้วยจำนวนที่มีแค่หลักสิบผมเลยเลือกทำ manual แทนที่จะไปเขียน code ที่มีความซับซ้อนในระดับนึง

2. SCSS darken, lighten

  • darken, lighten เป็น feature หนึ่งของ scss​ ซึ่งหลักๆ จะช่วยเพิ่มความสว่าง/มืดของสีนั้นๆ ได้
  • วิธีแก้ปัญหาจริงๆ แล้ว (ในอนาคต) อาจจะสามารถใช้ native function ของ css (relative color - CSS color module level 5) ที่ตอนนี้กำลังอยู่ในขั้นตอน draft อยู่ได้ แต่แน่นอนว่าเราก็ไม่ได้อยากรอครับ
  • ดังนั้นผมเลยเลือก map สีแบบ manual ด้วยการเพิ่ม darken / lighten ให้กับสีนั้นตรงๆ ท้ายที่สุดก็จะได้สีเดียวกับที่ใช้ darken / lighten หลังจากนั้นอาจจจะเขียน codemod, ทำ replacement หรือวิธีอะไรก็ได้เพื่อแก้ไขส่วนที่ใช้ darken / lighten
  • tool สำหรับการ map สีนั้นมีคนเขียนไว้ค่อนข้างเยอะ ดังนั้นจะเลือกอันไหนก็ได้ ซึ่ง codepen นี้เป็นอันที่ผมใช้ครับ https://codepen.io/baudoin/pen/kNyWJg
  • ทั้งนี้ในโปรเจค Wongnai ไม่ได้มีการใช้ darken / lighten มากขนาดนั้น แทนที่จะเขียน script เพื่อ migrate darken / lightenในทุกๆ ที่ การเลือก manual แก้ไปทีละจุดจะค่อนข้างง่ายและรวดเร็วกว่า

3. การ replace ส่วนที่ hard code เป็น hex color ตรงๆ และการ replace สีเก่าด้วยสีใหม่

  • ในความเป็นจริง Wongnai web ไม่ได้มีแค่โปรเจคเดียว แต่ยังมีโปรเจคอื่นๆ อีกดังนั้นคงไม่ใช่เรื่องดีถ้าเราจะหาสีเหล่านั้น แล้วมาไล่ manual replace เป็นสีใหม่ทีละจุด
  • ในส่วนนี้ผมเลยเลือกจะใช้ codemod เขียน script ที่จะอ่านไฟล์ต่างๆ และทำการ replace hex color เป็น css color variable
// ตัวอย่างจุดที่มีการ hard code สีไว้// constant ทั่วไป
const color = '#000' >>> const color = var(--black)
// styled-component
const A = styled.div`
color: #000; >>> color: ${'var(--black)'};
`
// jsx
<div color="#000" /> >>> <div color="var(--black)" />
  • จากตัวอย่างข้างบนจะเห็นว่าการ hard code สีจริงๆ มีอยู่ค่อนข้างหลากหลาย ประเด็นหลักๆ ที่ต้องคำนึงคือหลังจาก replace ด้วย codemod เสร็จแล้ว syntax ควรจะต้องถูกต้อง
  • ส่วน tool ที่เลือกใช้จะเป็น jscodeshift ที่เบื้องหลังจะสามารถทำ AST (Abstract Syntax Tree) ได้ มาช่วยเขียน script migrate สีครับ

External Color (library)

มีหลายๆ use case ที่ไม่สามารถใช้ CSS Variable ตรงๆ ได้ ทำให้เราต้องทำ tool บางอย่างมาเพื่อ migrate CSS Varนี้เป็น hex color ก่อนจะเอาไปใช้งานจริง

ยกตัวอย่างเช่น

  • library ต่างๆ ที่สามารถ custom สีได้ด้วยการส่งสีที่ต้องการเข้าไป แต่ในความเป็นจริงแล้วไม่ใช่ทุก lib ที่จะรองรับการใช้ css var
  • สีที่ถูกนำมาใช้ตั้งแต่ complier time ทำให้ไม่สามารถใช้ css var ได้ (อย่างบาง use case ของการใช้ styled-component ก็จะติดปัญหานี้)
  • สีที่ใช้ใน markup สำหรับ serve บน ssr ถ้าไม่ได้ครอบ :root ไว้ ก็จะทำให้ไม่สามารถใช้ css var ได้ตรงๆ เช่นกัน
  • การ combine CSS Var กับ opacity ซึ่งปกติจะอยู่ในรูป rgba(…) ที่เรานิยมใช้กัน ซึ่ง css var ไม่สามารถใช้กับ rgba ตรงๆ ได้ครับ (เราอาจจะเลี่ยงไปใช้ opacity แทนได้ โดยมี trade off เล็กๆ คือต้องเพิ่ม code ขึ้นมาอีกหนึ่งบรรทัดและกับ code ที่อาจจะซับซ้อนขึ้นเพราะกระทบกับทั้ง element นั้น) แต่ที่เลี่ยงไม่ได้คือ linear gradient และสีข้างในถูก defined เป็น rgba

วิธีที่ง่ายที่สุดแน่นอนคือการ hard code แต่ไม่ใช้สำหรับ legacy project แน่นอน ดังนั้นผมจำทำออกมาในลักษณะที่มีการเรียกใช้ function เพื่อแปลง css var ให้กลับเป็น hex color

สำหรับ step คร่าวๆ ของการเปลี่ยน css var ให้ใช้กับ rgba ได้ตามนี้ครับ

css var -> hex color -> rgb/rgba
  1. css var to hex color

code ที่ใช้ทำท่าดังกล่าวเริ่มแรกจะมีประมาณนี้ครับ

const black = 'var(--black)'
const A = toHex(black)

แต่ในท่าด้านบนมีข้อเสียคือการที่ต้อง import function มาก่อนเสมอถึงจะใช้งานได้ เพื่อให้ง่ายผมจึงปรับให้ออกมาลักษณะตามโค้ดด้านล่างแทน โดยเบื้องหลังก็เป็น proxy function ธรรมดาครับ

const A = black.toHex()

2. hex color to rgba

เมื่อนำมา implement กับส่วนที่ใช้ rgba จะทำให้ code ออกมาในลักษณะนี้ครับ

background-color: linear-gradient(0deg, black.toHex(), white.toHex());

SSR และ CSR

Server side rendering เป็นสิ่งหนึ่งที่ขาดไม่ได้สำหรับเว็บที่ต้องการทำ SEO แต่อีกแง่หนึ่งมันย่อมทำให้การ implement ยากขึ้นในหลายๆ ด้าน และ Dark Mode ก็เป็นหนึ่งในนั้นครับ

ปัญหาหลักๆ ที่เกิดขึ้นใน server side ก่อนจะ hydrate ไปที่ client side ซึ่งใช้ styled-component มีอยู่ 2 อย่าง

  1. style หลังจาก rehydrate แล้วจะไม่ถูก render ใหม่อีกครั้งใน CSR (ในกรณีที่ไม่จำเป็นต้องมีการ render ใหม่ เช่น styled-component เปล่าๆ) ทำให้สุดท้ายสีใน CSR และ SSR ไม่ตรงกัน
  • สิ่งที่ต้องทำคือ ทำอย่างไรก็ได้ให้สีใน server และ client เหมือนกัน ดังนั้นในทุก utility function ที่เขียนขึ้นมาเพื่อให้ใช้กับ Dark Mode ก็ควรคำนึงเรื่องการทำงานได้ใน server side ได้ด้วย
  • วิธีหนึ่งที่ผมทำบ่อยๆ คือเซ็ต styled ไว้ใน function เพื่อให้ถูก trigger อีกครั้งบน CSR
const applyColor = () => black.toHex()

const ColorWithApplyStyled = styled.div`
color: ${applyColor};
`
  • หรืออีกวิธีอาจจะเป็นการทำ anonymous function ที่ return color ก็สามารถทำให้ trigger บน client side ได้เช่นกันครับ
const ColorStyled = styled.div`
color: ${() => black.toHex()};
`
  • ข้อเสียของการทำวิธีนี้คือ child ที่ถูก provide ด้วย styled นี้ก็จะถูก render ใหม่ จึงควรระวังเรื่องนี้ด้วยครับ

** ปัญหานี้จริงๆ ไม่ใช่บัคแต่คือ know issue เป็นสิ่งที่ styled-component เวอร์ชั่นหลังๆ มีขึ้น เพื่อ performance ครับ

2. โหมดสีจาก device system (หาก device เซ็ตเป็น Dark Mode บนเว็บก็ควรจะถูกเซ็ตด้วยเช่นกัน)

  • อันที่จริงแล้ว ข้อนี้ไม่เชิงเป็นปัญหา แต่ต้องบอกว่าเป็นความยุ่งยากมากกว่า
  • โดยปกติถ้าเป็นโปรเจค CSR การจะดึง mode จาก device จะสามารถใช้ window media queries prefers-color-scheme เพื่อเช็ค mode ได้ แต่ใน SSR นั้นไม่สามารถทำท่านี้ได้
  • สิ่งที่ต้องทำคือเซ็ต accept-ch: sec-ch-prefers-color-scheme ไว้ใน header ของ response และหลังจาก preflight request เราจะสามารถอ่าน sec-ch-prefers-color-scheme บน header ของ request และสามารถนำไปใช้อ้างอิง device mode ได้ครับ
  • อีกสิ่งที่ต้องทำต่อมาคือการ sync ระหว่าง mode ใน SSR และ CSR เพื่อไม่ให้สีเพี้ยนตอนที่ direct เข้ามาใน web ครั้งแรก วิธีทำนั้นค่อนข้างหลากหลาย ไม่ว่าจะเป็นการโยน mode ข้ามไป CSR หรือ pass ใส่ context เพื่อให้สะดวกต่อการหยิบไปใช้
  • และถ้าเราไม่ได้เก็บ mode ไว้ใน db สิ่งที่ต้องทำเพิ่มคือการเซ็ต mode ไว้ใน storage หากเป็น CSR project จะใช้ localStorage หรือ cookie ก็ได้ แต่ถ้าเป็น SSR project จำเป็นที่ต้องใช้ cookie เพื่อให้อ่านค่าได้ใน SSR ครับ

Dark Color / Light Color

ไม่ใช่ทุกที่ที่เมื่ออยู่ใน Dark Mode แล้วสีจะต้องถูกเปลี่ยนเป็น dark color อาทิเช่น

text สีขาวที่อยู่บน shadow

ในเคสนี้ text ก็ควรจะเป็นสีขาวเสมอแม้จะอยู่ใน Dark Mode ดังนั้นจึงต้องมี utility function เกี่ยวกับสีที่สามารถ fix / convert สีเป็นโหมดต่างๆ ได้

และเหมือนกับที่เล่าไป เพื่อให้ง่ายต่อการใช้งาน นอกจาก .toHex แล้วผมจึงทำอีก 2 อย่างเพิ่มขึ้นมาครับ

black.light()
black.dark()

เมื่อรวมกับปัญหาเรื่องที่ external lib จำเป็นต้องใช้ hex color ดังนั้น .light() , .dark() ที่ทำมานี้จึงสามารถแปลงเป็น hex color ได้เช่นกัน

black.light().toHex()
black.dark().toHex()

Meta tag

บน mobile web โดยปกติแล้วบริเวณ​ background ของ url section ถ้าไม่ได้เซ็ตอะไรไว้จะมีสี default ไว้เป็นสีขาว ดังนั้นอีกสิ่งที่ต้องทำเพิ่มคือเซ็ต background นี้ให้ dynamic ตาม mode ของเว็บเรา

Meta tag นั้นจะมี theme-color ให้เซ็ตสีที่ว่านี้ได้ โดยวิธีเซ็ตอาจจะเซ็ตสีตรงๆ หรือเซ็ตสีโดยอิงจาก media prefers-color-scheme ก็ได้เช่นกันครับ

<meta name="theme-color" content="black"> 
<meta name="theme-color" media="(prefers-color-scheme: dark)" content="black">

เพื่อให้สะดวกผมจะใช้ ReactHelmet และ utility tool ที่ทำมามาช่วยเซ็ต meta tag ไว้บน header (จริงๆ ไม่จำเป็นต้องอยู่ใน header ก็ได้) ซึ่งจะทำให้โค้ดออกมาในลักษณะประมาณนี้ครับ

<ReactHelmet>
<meta name="theme-color" content={white.toHex()} />
</ReactHelmet>

หลังจากเราสามารถ solve ปัญหาทั้งหมด รวมถึง apply ทุกอย่างกับ tool ที่ทำไว้ แทบทั้งเว็บก็เกือบจะกลายเป็น Dark Mode อย่างที่เราตั้งเป้าไว้แล้วครับ จะเหลือเพียงบางจุดที่ต้องไล่แก้ manual อาทิเช่น

Icon

  • ในกรณีที่ icon เป็น svg เราสามารถเปลี่ยนสีให้เป็น currentColor เพื่อดึงสีจาก parent แทน ซึ่งจะทำให้เราได้ dynamic icon ที่จะเปลี่ยนสีไปตาม mode ของเว็บเราครับ
const SvgIcon = () => <svg color="currentColor">..</svg>
  • ในกรณีที่ไม่มี svg การเลือกไปใช้ css เพื่อทำ invert color ก็เป็นอีกทางเลือกหนึ่ง เพียงแต่เราจะไม่สามารถ control สีได้ครับ (โดยผมจะเลือกปล่อย icon เหล่านี้ไว้ เพราะมีจำนวนไม่มาก)
img {
filter: invert(100%);
}

Sponser Page

  • บางหน้าใน wongnai ทำไว้สำหรับลูกค้าโดยเฉพาะ ซึ่งลูกค้าแต่ละรายก็อาจจะมีสีเฉพาะของแบรนด์ที่ไม่ควรไปเปลี่ยนเองตามใจ ทำให้ผมเลือกใจ force ทั้งหน้านั้นให้เป็น light mode เพื่อเลี่ยงปัญหาที่จะตามมาครับ
  • วิธีคือ การเซ็ต router config เพื่อแก้ theme provider ที่ครอบอยู่ที่ root ของแต่ละหน้า (ซึ่งท่านี้นอกจากการ fix mode แล้วยังทำให้สามารถ fix theme ของแต่ละหน้าได้ง่ายด้วย)

** การทำ router config เพื่อให้สามารถ force mode แยกหน้าได้ ข้อดีคือทำให้ตอนที่เรา implement Dark Mode สามารถค่อยๆ ทำแล้วปล่อยขึ้น production ไปทีละหน้าได้

White text on black background

  • text สีขาวบนพื้นหลังสีดำ ควรที่จะไม่ถูกเปลี่ยนในทุก mode ตามที่เล่าไปด้านบน ซึ่งส่วนนี้การจะทำ codemod มาอ่านอาจจะค่อนข้างจะวุ่นวาย ผมเลยเลือกแก้ manual ที่สะดวกและรวดเร็วกว่าครับ

CMS Page

  • บางหน้าใน wongnai เป็น content ที่ทำบน CMS และมีการ inject style ในตัว เคสแย่สุดคือมีการทำไว้บน CMS เลยดังนั้นจึงเป็นอีกจุดที่ต้องไปเช็คครับ
  • ด้วยความที่เราใช้ css var ทำให้ style ใน CMS ก็สามารถใช้ var เดียวกันกับใน project เพื่อให้รองรับ Dark Mode ได้ครับ (ในความเป็นจริงการเขียน style บน CMS มีค่อนข้างน้อย เพราะคนเขียนมักเป็น content creator)

ขั้นตอนสุดท้ายคือการไล่เช็กทุกหน้า และทุก feature เท่าที่จะเป็นไปได้ รวมถึงปล่อยขึ้น dev domain เป็นช่วงระยะเวลาหนึ่ง เพื่อให้คนอื่นๆ ช่วยเช็คถึงความผิดเพี้ยนของสี รวมถึงลดงาน QA ไปในตัว และเพื่อให้มั่นใจว่าจะไม่มีหรือเกิดสี่เพี้ยนน้อยที่สุดตอนนำขึ้น production ครับ

ในขั้นตอนนี้ฟังแล้วอาจจะดูเป็นงานถึก เพราะจำเป็นต้องไล่เช็ค ถ้ามีสีเพี้ยนก็ต้องไปแก้ ยิ่งถ้ามีจำนวนหน้าเยอะๆ ก็ยิ่งต้องเสียเวลามาก แต่จริงๆ แล้วผมใช้เวลาประมาณ 2–3 วันก็สามารถเช็คและแก้ไขหน้าเว็บ wongnai ที่มีกว่า 120 หน้าได้ทั้งหมดครับ

ปัจจัยหลักที่ทำให้ใช้เวลาน้อยเป็นเพราะตอนที่เราเขียนโค้ด เราค่อนข้างเน้นเรื่องการใช้ Component กลางเพื่อความสะดวกในการ maintain ทำให้หลายๆ ครั้งเมื่อแก้เสร็จหน้าหนึ่งแล้ว หน้าอื่นๆ ก็จะได้รับผลพลอยได้ถูกแก้ตามไปด้วย

อีกปัจจัยคือ tool ที่ทำมาครับ อาจจะฟังดูอวยตัวเองนิดๆ แต่จริงๆ แล้วผมคิดว่ายิ่งเราสามารถออกแบบให้ใช้งานง่าย และครอบคลุม use case ได้มากเท่าไรก็จะสามารถลดเวลาในการ implement จริงไปได้ครับ

Conclusion

หลังจากเล่ามาค่อนข้างเยอะ จะขอสรุป flow ทั้งหมดของผมในการ migrate ทั้งเว็บเป็น Dark Mode ตรงนี้ครับ

  • เตรียม design system, สีใน light / dark mode ทำให้เป็น CSS Variable
  • ลิสต์ส่วนที่ต้องแก้สีทั้งหมดในโปรเจค ก่อนจะเขียน script migrate hex color ให้เป็น css variable
  • ทำ tool .toHex , .light() , .dark()
  • ทำ router config (react) ให้รองรับการ fix mode
  • manual migration ไล่แก้จุดที่เหลือจากด้านบน

อาจจะเป็นขั้นตอนง่ายๆ ไม่กี่ขั้นตอน แต่หากเป็น legacy project และวาง structure มาไม่ค่อยดี อาจจะต้องเสียเวลาเพิ่มขึ้นในการ implement แต่ละขั้นตอนครับ

ทั้งหมดที่เล่ามานี้อาจจะไม่ใช่ best practice ทั้งหมด บางท่าอาจจะดีกับในสถานการณ์หนึ่ง แต่ก็อาจจะไม่ดีกับอีกสถานการณ์หนึ่ง แต่ผมเชื่อว่าวิธีที่ดีสุดอาจจะไม่ใช่คำตอบที่ดีที่สุดเสมอไปครับ การเอาไปปรับใช้หรือหาแนวคิดที่เหมาะกับสถานการณ์นั้นๆ น่าจะเป็นวิธีที่ดีที่สุดมากกว่า

ขอให้สนุกกับ Dark Mode ครับ

wongnai.com — Dark Mode

สามารถไปลองเล่น Wongnai Dark Mode ตามลิงค์นี้ได้นะครับ https://www.wongnai.com/me/display-settings

ขายของเล็กน้อย LINE MAN Wongnai เราเปิดรับสมัครพนักอยู่เรื่อยๆ ส่วน Intern/Co-op เรารับตลอดทั้งปีสามารถมาสมัครกันได้นะครับ
(อย่าลืม ref: Pipe Kittapon ด้วยนะะ)

--

--