สีที่ชอบ: สวัสดีความมืด เพื่อนเก่าของฉัน

เกินจริงหรือจำเป็น ดูข้อมูลทั้งหมดเกี่ยวกับโหมดมืดและวิธีรองรับเพื่อประโยชน์ของผู้ใช้

บทนำ

โหมดมืดก่อนโหมดมืด

จอคอมพิวเตอร์กรีนสกรีน
กรีนสกรีน (แหล่งที่มา)

เราพัฒนาโหมดมืดมาอย่างยาวนาน ในช่วงเริ่มต้นของคอมพิวเตอร์ส่วนบุคคล โหมดมืดไม่ใช่ตัวเลือก แต่เป็นสิ่งที่ต้องทำเนื่องจากจอภาพคอมพิวเตอร์ CRT แบบโมโนโครมทำงานโดยการยิงลำแสงอิเล็กตรอนไปยังหน้าจอเรืองแสง และฟอสฟอร์ที่ใช้ใน CRT รุ่นแรกๆ เป็นสีเขียว เนื่องจากข้อความแสดงเป็นสีเขียวและส่วนที่เหลือของหน้าจอเป็นสีดํา กล้องรุ่นเหล่านี้จึงมักเรียกว่ากรีนสกรีน

การประมวลผลคำแบบสีเข้มบนพื้นขาว
สีดําบนพื้นขาว (แหล่งที่มา)

CRT สีที่เปิดตัวตามมาจะแสดงสีได้หลายสีโดยใช้ฟอสฟอรัสสีแดง เขียว และน้ำเงิน โดยสร้างสีขาวด้วยการกระตุ้นโฟสฟอรัสทั้ง 3 ชนิดพร้อมกัน เมื่อเกิด WYSIWYG ที่ล้ำสมัยขึ้น Desktop Publishing ก็ได้รับความนิยมมากขึ้น แนวคิดในการสร้างเอกสารเสมือนให้คล้ายกับกระดาษจริงก็เริ่มแพร่หลาย

หน้าเว็บแบบสีดําบนพื้นขาวในเบราว์เซอร์ WorldWideWeb
เว็บเบราว์เซอร์ WorldWideWeb (แหล่งที่มา)

นี่เป็นจุดเริ่มต้นของเทรนด์การออกแบบสีเข้มบนสีขาว และเทรนด์นี้ยังใช้กับเว็บยุคแรกๆ ที่ใช้เอกสาร เบราว์เซอร์แรกของโลกอย่าง WorldWideWeb (อย่าลืมว่าตอนนั้นยังไม่มีการคิดค้น CSS) แสดงหน้าเว็บด้วยวิธีนี้ เกร็ดความรู้: เบราว์เซอร์ที่ 2 ของโลกอย่าง Line Mode Browser ซึ่งเป็นเบราว์เซอร์ที่ใช้เทอร์มินัลมีสีเขียวบนพื้นหลังสีดำ ปัจจุบันหน้าเว็บและเว็บแอปมักออกแบบให้มีข้อความสีเข้มบนพื้นหลังสีอ่อน ซึ่งเป็นค่าเริ่มต้นพื้นฐานที่เขียนไว้ในสไตล์ชีต User Agent รวมถึงของ Chrome ด้วย

ใช้สมาร์ทโฟนขณะนอนอยู่บนเตียง
การใช้สมาร์ทโฟนบนเตียง (แหล่งที่มา: Unsplash)

ยุคของ CRT นั้นผ่านพ้นไปนานแล้ว การรับชมและการสร้างเนื้อหาได้เปลี่ยนไปใช้อุปกรณ์เคลื่อนที่ที่ใช้หน้าจอ LCD แบบมีแสงด้านหลังหรือหน้าจอ AMOLED ที่ประหยัดพลังงาน คอมพิวเตอร์ แท็บเล็ต และสมาร์ทโฟนที่เล็กลงและพกพาได้มากขึ้นทำให้เกิดรูปแบบการใช้งานใหม่ๆ งานอดิเรก เช่น การท่องเว็บ การเขียนโค้ดเพื่อความสนุก และการเล่นเกมระดับสูงมักเกิดขึ้นหลังเลิกงานในสภาพแวดล้อมที่สลัว ผู้คนยังใช้อุปกรณ์บนเตียงในเวลากลางคืนด้วย ยิ่งผู้คนใช้อุปกรณ์ในที่มืดมากเท่าใด แนวคิดในการกลับไปใช้โหมดสว่างบนพื้นหลังสีเข้มก็ยิ่งได้รับความนิยมมากขึ้นเท่านั้น

เหตุผลที่ควรใช้โหมดมืด

โหมดมืดเพื่อความสวยงาม

เมื่อมีคนถามว่าเหตุใดผู้ใช้จึงชอบหรือต้องการโหมดมืด คำตอบที่ได้รับความนิยมสูงสุดคือ"เพราะสบายตา" ตามมาด้วย"เพราะดูหรูหราและสวยงาม" Apple เขียนไว้อย่างชัดเจนในเอกสารประกอบสำหรับนักพัฒนาแอปเกี่ยวกับโหมดมืดว่า "การเลือกว่าจะเปิดใช้ลักษณะที่ปรากฏแบบสว่างหรือมืดนั้นขึ้นอยู่กับความชอบของผู้ใช้ส่วนใหญ่ และอาจไม่เกี่ยวข้องกับสภาพแสงโดยรอบ"

CloseView ใน Mac OS System 7 ที่มี
System 7 CloseView (Source)

โหมดมืดเป็นเครื่องมือการช่วยเหลือพิเศษ

นอกจากนี้ ยังมีผู้ที่จำเป็นต้องใช้โหมดมืดและใช้โหมดดังกล่าวเป็นเครื่องมือการช่วยเหลือพิเศษอีกอย่างหนึ่ง เช่น ผู้ใช้ที่มีสายตาเลือนราง เครื่องมือการช่วยเหลือพิเศษประเภทนี้ที่พบได้เร็วที่สุดคือฟีเจอร์ CloseView ของ System 7 ซึ่งมีปุ่มสลับสำหรับสีดำบนสีขาวและสีขาวบนสีดํา แม้ว่า System 7 จะรองรับสี แต่อินเทอร์เฟซผู้ใช้เริ่มต้นยังคงเป็นสีขาวดำ

การใช้งานที่อิงตามการกลับสีเหล่านี้แสดงให้เห็นถึงจุดอ่อนเมื่อมีการนําสีมาใช้ งานวิจัยของ Szpiro et al. เกี่ยวกับวิธีที่ผู้ที่มีสายตาเลือนรางเข้าถึงอุปกรณ์คอมพิวเตอร์พบว่าผู้ใช้ทุกคนที่สัมภาษณ์ไม่ชอบรูปภาพที่กลับสี แต่ผู้ใช้จำนวนมากชอบข้อความสีอ่อนบนพื้นหลังสีเข้ม Apple รองรับความต้องการของผู้ใช้ด้วยฟีเจอร์ที่เรียกว่าการกลับสีอัจฉริยะ ซึ่งจะกลับสีบนจอแสดงผล ยกเว้นรูปภาพ สื่อ และแอปบางแอปที่ใช้สไตล์สีเข้ม

ภาวะสายตาต่ำรูปแบบพิเศษอย่างหนึ่งคือ Computer Vision Syndrome หรือที่เรียกว่า Digital Eye Strain ซึ่งหมายถึง"ปัญหาเกี่ยวกับดวงตาและสายตาที่เชื่อมโยงกับการใช้คอมพิวเตอร์ (รวมถึงเดสก์ท็อป แล็ปท็อป และแท็บเล็ต) และจอแสดงผลอิเล็กทรอนิกส์อื่นๆ (เช่น สมาร์ทโฟนและอุปกรณ์การอ่านอิเล็กทรอนิกส์)" มีข้อเสนอแนะว่าการใช้อุปกรณ์อิเล็กทรอนิกส์ของวัยรุ่น โดยเฉพาะในเวลากลางคืน จะทำให้มีความเสี่ยงมากขึ้นที่จะนอนหลับได้ไม่นาน ใช้เวลานานขึ้นในการเข้าสู่การนอนหลับ และนอนหลับไม่เพียงพอ นอกจากนี้ การรายงานที่แพร่หลายยังระบุว่าการสัมผัสกับแสงสีฟ้ามีส่วนเกี่ยวข้องกับการควบคุมจังหวะการตื่นและนอนหลับตามวันและวงจรการนอนหลับ และสภาพแวดล้อมที่มีแสงไม่สม่ำเสมออาจทำให้นอนหลับไม่เพียงพอ ซึ่งอาจส่งผลต่ออารมณ์และประสิทธิภาพในการทำงานได้ ตามการวิจัยของ Rosenfield หากต้องการจำกัดผลกระทบเชิงลบเหล่านี้ คุณสามารถลดแสงสีฟ้าได้โดยการปรับอุณหภูมิสีของจอแสดงผลผ่านฟีเจอร์ต่างๆ เช่น Night Shift ของ iOS หรือNight Light ของ Android รวมถึงหลีกเลี่ยงแสงที่สว่างจ้าหรือแสงที่ผิดปกติโดยทั่วไปผ่านธีมมืดหรือโหมดมืด

การประหยัดพลังงานในโหมดมืดบนหน้าจอ AMOLED

สุดท้ายนี้ โหมดมืดเป็นที่รู้จักกันดีว่าช่วยประหยัดพลังงานได้มากในหน้าจอ AMOLED กรณีศึกษาของ Android ที่มุ่งเน้นแอปยอดนิยมของ Google เช่น YouTube แสดงให้เห็นว่าการประหยัดพลังงานอาจทำได้ถึง 60% วิดีโอด้านล่างมีรายละเอียดเพิ่มเติมเกี่ยวกับกรณีศึกษาเหล่านี้และการประหยัดพลังงานต่อแอป

การเปิดใช้งานโหมดมืดในระบบปฏิบัติการ

หลังจากที่ได้พูดถึงเหตุผลที่โหมดมืดสำคัญกับผู้ใช้จำนวนมากแล้ว เรามาทบทวนวิธีรองรับโหมดนี้กัน

การตั้งค่าโหมดมืดใน Android Q
การตั้งค่าธีมมืดของ Android Q

ระบบปฏิบัติการที่รองรับโหมดมืดหรือธีมมืดมักจะมีตัวเลือกให้เปิดใช้งานในส่วนการตั้งค่า ใน macOS X ตัวเลือกนี้จะอยู่ในส่วนทั่วไปของค่ากำหนดของระบบและเรียกว่าลักษณะที่ปรากฏ (ภาพหน้าจอ) ส่วนใน Windows 10 ตัวเลือกนี้จะอยู่ในส่วนสีและเรียกว่าเลือกสี (ภาพหน้าจอ) สำหรับ Android Q คุณจะดูได้ในการแสดงผลในรูปแบบสวิตช์ธีมมืด (ภาพหน้าจอ) และสำหรับ iOS 13 คุณจะเปลี่ยนลักษณะที่ปรากฏได้ในส่วนการแสดงผลและความสว่างของการตั้งค่า (ภาพหน้าจอ)

คิวรีสื่อ prefers-color-scheme

ข้อมูลทางทฤษฎีอีกเล็กน้อยก่อนที่จะไปต่อ ข้อความค้นหาสื่อช่วยให้ผู้เขียนทดสอบและค้นหาค่าหรือฟีเจอร์ของ User Agent หรืออุปกรณ์แสดงผลได้ โดยไม่ขึ้นอยู่กับเอกสารที่กำลังแสดงผล โดยจะใช้ในกฎ @media ของ CSS เพื่อใช้สไตล์กับเอกสารแบบมีเงื่อนไข และในบริบทและภาษาอื่นๆ อีกมากมาย เช่น HTML และ JavaScript Media Queries ระดับ 5 เปิดตัวฟีเจอร์สื่อตามความต้องการของผู้ใช้ ซึ่งเป็นวิธีที่เว็บไซต์จะตรวจหาวิธีที่ต้องการของผู้ใช้ในการแสดงเนื้อหา

ระบบจะใช้ฟีเจอร์สื่อ prefers-color-scheme เพื่อตรวจจับว่าผู้ใช้ได้ขอให้หน้าเว็บใช้ธีมสีสว่างหรือธีมมืด ซึ่งจะทำงานกับค่าต่อไปนี้

  • light: บ่งบอกว่าผู้ใช้ได้แจ้งให้ระบบทราบว่าต้องการหน้าเว็บที่มีธีมสว่าง (ข้อความสีเข้มบนพื้นหลังสีอ่อน)
  • dark: บ่งบอกว่าผู้ใช้ได้แจ้งให้ระบบทราบว่าต้องการใช้หน้าเว็บที่มีธีมมืด (ข้อความสีอ่อนบนพื้นหลังสีเข้ม)

การรองรับโหมดมืด

ตรวจสอบว่าเบราว์เซอร์รองรับโหมดมืดหรือไม่

เนื่องจากโหมดมืดมีการรายงานผ่าน Media Query คุณจึงตรวจสอบได้อย่างง่ายดายว่าเบราว์เซอร์ปัจจุบันรองรับโหมดมืดหรือไม่โดยดูว่า Media Query prefers-color-scheme ตรงกันหรือไม่ โปรดสังเกตว่าเราไม่ได้ใส่ค่าใดๆ เลย แต่ตรวจสอบว่าคําค้นหาสื่อเพียงอย่างเดียวตรงกันหรือไม่

if (window.matchMedia('(prefers-color-scheme)').media !== 'not all') {
  console.log('🎉 Dark mode is supported');
}

ขณะเขียนบทความนี้ Chrome และ Edge เวอร์ชัน 76, Firefox เวอร์ชัน 67 และ Safari เวอร์ชัน 12.1 ใน macOS และเวอร์ชัน 13 ใน iOS รองรับ prefers-color-scheme ทั้งบนเดสก์ท็อปและอุปกรณ์เคลื่อนที่ (หากมี) สำหรับเบราว์เซอร์อื่นๆ ทั้งหมด คุณสามารถดูที่หัวข้อฉันใช้ตารางการสนับสนุนได้ไหม

การเรียนรู้เกี่ยวกับค่ากําหนดของผู้ใช้ ณ เวลาส่งคําขอ

ส่วนหัวคำแนะนำไคลเอ็นต์ Sec-CH-Prefers-Color-Scheme ช่วยเว็บไซต์ในการรับค่ากำหนดชุดสีของผู้ใช้ (ไม่บังคับ) ณ เวลาส่งคำขอ ซึ่งช่วยให้เซิร์ฟเวอร์แทรก CSS ที่ถูกต้องในหน้าเว็บได้ จึงหลีกเลี่ยงการแสดงธีมสีที่ไม่ถูกต้องเป็นระยะเวลาสั้นๆ

การใช้งานโหมดมืด

สุดท้ายนี้ มาดูกันว่าการรองรับโหมดมืดจะเป็นอย่างไรในทางปฏิบัติ เช่นเดียวกับHighlander โหมดมืดมีได้เพียงโหมดเดียวเท่านั้น นั่นคือโหมดมืดหรือโหมดสว่าง แต่จะใช้ทั้ง 2 โหมดไม่ได้ เหตุผลที่เราพูดถึงเรื่องนี้ เนื่องจากข้อเท็จจริงนี้ควรส่งผลต่อกลยุทธ์การโหลด โปรดอย่าบังคับให้ผู้ใช้ดาวน์โหลด CSS ในเส้นทางการแสดงผลที่สำคัญซึ่งใช้สำหรับโหมดที่ผู้ใช้ไม่ได้ใช้อยู่ เราจึงแยก CSS สําหรับแอปตัวอย่างซึ่งแสดงคําแนะนําต่อไปนี้ในทางปฏิบัติออกเป็น 3 ส่วนเพื่อเลื่อน CSS ที่ไม่สําคัญ ดังนี้

  • style.css ที่มีกฎทั่วไปซึ่งใช้ในเว็บไซต์โดยรวม
  • dark.css ที่มีเฉพาะกฎที่จำเป็นสำหรับโหมดมืด
  • light.css ที่มีเฉพาะกฎที่จำเป็นสำหรับโหมดสว่าง

กลยุทธ์การโหลด

ส่วน light.css และ dark.css จะโหลดแบบมีเงื่อนไขด้วยคําค้นหา <link media> ในช่วงแรก เบราว์เซอร์บางรุ่นจะไม่รองรับ prefers-color-scheme (ซึ่งตรวจพบได้โดยใช้รูปแบบด้านบน) ซึ่งเราจัดการแบบไดนามิกด้วยการโหลดไฟล์ light.css เริ่มต้นผ่านองค์ประกอบ <link rel="stylesheet"> ที่แทรกแบบมีเงื่อนไขในสคริปต์อินไลน์ขนาดเล็ก (แบบสว่างเป็นตัวเลือกที่ไม่บังคับ เราอาจทำให้แบบมืดเป็นประสบการณ์การใช้งานสำรองเริ่มต้นได้เช่นกัน) เพื่อหลีกเลี่ยงการกะพริบของเนื้อหาที่ไม่มีการจัดรูปแบบ เราจึงซ่อนเนื้อหาของหน้าเว็บไว้จนกว่า light.css จะโหลด

<script>
  // If `prefers-color-scheme` is not supported, fall back to light mode.
  // In this case, light.css will be downloaded with `highest` priority.
  if (window.matchMedia('(prefers-color-scheme: dark)').media === 'not all') {
    document.documentElement.style.display = 'none';
    document.head.insertAdjacentHTML(
      'beforeend',
      '<link rel="stylesheet" href="/light.css" onload="document.documentElement.style.display = \'\'">',
    );
  }
</script>
<!--
  Conditionally either load the light or the dark stylesheet. The matching file
  will be downloaded with `highest`, the non-matching file with `lowest`
  priority. If the browser doesn't support `prefers-color-scheme`, the media
  query is unknown and the files are downloaded with `lowest` priority (but
  above I already force `highest` priority for my default light experience).
-->
<link rel="stylesheet" href="/dark.css" media="(prefers-color-scheme: dark)" />
<link
  rel="stylesheet"
  href="/light.css"
  media="(prefers-color-scheme: light)"
/>
<!-- The main stylesheet -->
<link rel="stylesheet" href="/style.css" />

สถาปัตยกรรมสไตล์ชีต

เราใช้ตัวแปร CSS ให้ได้สูงสุด ซึ่งช่วยให้ style.css ทั่วไปของเราเป็นแบบทั่วไปจริงๆ และการปรับแต่งโหมดสว่างหรือโหมดมืดทั้งหมดจะเกิดขึ้นในไฟล์อีก 2 ไฟล์อย่าง dark.css และ light.css ด้านล่างนี้คือตัวอย่างสไตล์จริง ซึ่งน่าจะเพียงพอที่จะสื่อถึงแนวคิดโดยรวม ฉันประกาศตัวแปร 2 ตัว ได้แก่ -⁠-⁠color และ -⁠-⁠background-color ซึ่งสร้างธีมพื้นฐานสีเข้มบนพื้นหลังสีอ่อนและสีอ่อนบนพื้นหลังสีเข้ม

/* light.css: 👉 dark-on-light */
:root {
  --color: rgb(5, 5, 5);
  --background-color: rgb(250, 250, 250);
}
/* dark.css: 👉 light-on-dark */
:root {
  --color: rgb(250, 250, 250);
  --background-color: rgb(5, 5, 5);
}

ใน style.css ฉันใช้ตัวแปรเหล่านี้ในกฎ body { … } เนื่องจากมีการกําหนดไว้ใน:root คลาสจำลอง CSS ซึ่งเป็นตัวเลือกที่แสดงองค์ประกอบ <html> ใน HTML และเหมือนกับตัวเลือก html ยกเว้นความเฉพาะเจาะจงที่สูงกว่า ตัวเลือกเหล่านี้จึงมีผลแบบเป็นลําดับขั้น ซึ่งเป็นประโยชน์สําหรับการประกาศตัวแปร CSS ร่วม

/* style.css */
:root {
  color-scheme: light dark;
}

body {
  color: var(--color);
  background-color: var(--background-color);
}

ในตัวอย่างโค้ดด้านบน คุณอาจสังเกตเห็นพร็อพเพอร์ตี้ color-scheme ที่มีค่า light dark ที่เว้นวรรค

ซึ่งจะบอกให้เบราว์เซอร์ทราบว่าแอปรองรับธีมสีใดบ้าง และช่วยให้เบราว์เซอร์เปิดใช้งานรูปแบบสไตล์ชีตของ User Agent รูปแบบพิเศษได้ ซึ่งมีประโยชน์ในกรณีต่างๆ เช่น ช่วยให้เบราว์เซอร์แสดงผลช่องแบบฟอร์มที่มีพื้นหลังสีเข้มและข้อความสีอ่อน ปรับแถบเลื่อน หรือเปิดใช้สีไฮไลต์ที่รับรู้ธีม รายละเอียดที่แน่นอนของ color-scheme ระบุไว้ในโมดูลการปรับสี CSS ระดับ 1

ส่วนที่เหลือก็แค่กำหนดตัวแปร CSS สำหรับสิ่งที่สำคัญในเว็บไซต์ การจัดระเบียบสไตล์ตามความหมายมีประโยชน์อย่างมากเมื่อใช้โหมดมืด เช่น แทนที่จะใช้ -⁠-⁠highlight-yellow ให้ลองเรียกตัวแปรว่า -⁠-⁠accent-color เนื่องจาก "yellow" อาจไม่ได้เป็นสีเหลืองในโหมดมืด หรือในทางกลับกัน ด้านล่างนี้คือตัวอย่างตัวแปรเพิ่มเติมที่เราใช้ในตัวอย่าง

/* dark.css */
:root {
  --color: rgb(250, 250, 250);
  --background-color: rgb(5, 5, 5);
  --link-color: rgb(0, 188, 212);
  --main-headline-color: rgb(233, 30, 99);
  --accent-background-color: rgb(0, 188, 212);
  --accent-color: rgb(5, 5, 5);
}
/* light.css */
:root {
  --color: rgb(5, 5, 5);
  --background-color: rgb(250, 250, 250);
  --link-color: rgb(0, 0, 238);
  --main-headline-color: rgb(0, 0, 192);
  --accent-background-color: rgb(0, 0, 238);
  --accent-color: rgb(250, 250, 250);
}

ตัวอย่างแบบเต็ม

ในการฝัง Glitch ต่อไปนี้ คุณจะเห็นตัวอย่างที่สมบูรณ์ซึ่งนำแนวคิดจากด้านบนไปปฏิบัติจริง ลองสลับโหมดมืดในการตั้งค่าระบบปฏิบัติการ แล้วดูว่าหน้าเว็บตอบสนองอย่างไร

ผลกระทบของการโหลด

เมื่อลองใช้ตัวอย่างนี้ คุณจะเห็นว่าเหตุใดฉันจึงโหลด dark.css และ light.css ผ่าน Media Query ลองสลับโหมดมืดและโหลดหน้าเว็บซ้ำ ไฟล์สไตล์ที่ไม่ตรงกันจะยังคงโหลดอยู่ แต่จะมีลำดับความสำคัญต่ำสุดเพื่อไม่ให้แย่งทรัพยากรกับเว็บไซต์ในขณะนี้

แผนภาพการโหลดเครือข่ายที่แสดงวิธีโหลด CSS ของโหมดมืดในโหมดสว่างโดยให้ลําดับความสําคัญต่ำสุด
เว็บไซต์ในโหมดสว่างจะโหลด CSS โหมดมืดที่มีลําดับความสําคัญต่ำสุด
แผนภาพการโหลดเครือข่ายที่แสดงวิธีโหลด CSS โหมดสว่างที่มีลําดับความสําคัญต่ำที่สุดในโหมดมืด
เว็บไซต์ในโหมดมืดจะโหลด CSS โหมดสว่างที่มีลําดับความสําคัญต่ำสุด
แผนภาพการโหลดเครือข่ายที่แสดงวิธีโหลด CSS ของโหมดมืดที่มีลําดับความสําคัญต่ำที่สุดในโหมดแสงสว่างเริ่มต้น
เว็บไซต์ในโหมดสว่างเริ่มต้นบนเบราว์เซอร์ที่ไม่รองรับ prefers-color-scheme จะโหลด CSS โหมดมืดที่มีลําดับความสําคัญต่ำสุด

การตอบสนองต่อการเปลี่ยนแปลงโหมดมืด

คุณสามารถติดตามการเปลี่ยนแปลงโหมดมืดผ่าน JavaScript ได้เช่นเดียวกับการเปลี่ยนแปลงการค้นหาสื่ออื่นๆ คุณสามารถใช้ตัวแปรนี้เพื่อเปลี่ยนFavicon ของหน้าเว็บแบบไดนามิก หรือเปลี่ยน <meta name="theme-color"> ที่กําหนดสีของแถบ URL ใน Chrome ตัวอย่างแบบเต็มด้านบนแสดงการทํางานของฟีเจอร์นี้ หากต้องการดูการเปลี่ยนแปลงสีธีมและไอคอน Fav ให้เปิดเดโมในแท็บแยกต่างหาก

const darkModeMediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
darkModeMediaQuery.addEventListener('change', (e) => {
  const darkModeOn = e.matches;
  console.log(`Dark mode is ${darkModeOn ? '🌒 on' : '☀️ off'}.`);
});

ตั้งแต่ Chromium 93 และ Safari 15 เป็นต้นไป คุณสามารถปรับสีตาม Media Query ด้วยแอตทริบิวต์ media ขององค์ประกอบสีธีม meta ระบบจะเลือกรายการแรกที่ตรงกัน เช่น คุณอาจมีสีหนึ่งสำหรับโหมดสว่างและอีกสีหนึ่งสำหรับโหมดมืด ณ เวลาที่เขียนบทความนี้ คุณจะกำหนดค่าเหล่านั้นในไฟล์ Manifest ไม่ได้ โปรดดูGitHub w3c/manifest#975

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

การแก้ไขข้อบกพร่องและการทดสอบโหมดมืด

การจําลอง prefers-color-scheme ในเครื่องมือสําหรับนักพัฒนาเว็บ

การเปลี่ยนรูปแบบสีทั้งระบบปฏิบัติการอาจสร้างความรำคาญได้อย่างรวดเร็ว ดังนั้นตอนนี้เครื่องมือสำหรับนักพัฒนาซอฟต์แวร์ของ Chrome จึงให้คุณจําลองรูปแบบสีที่ผู้ใช้ต้องการได้ ในลักษณะที่ส่งผลต่อแท็บที่มองเห็นอยู่ในปัจจุบันเท่านั้น เปิดเมนูคำสั่ง เริ่มพิมพ์ Rendering เรียกใช้คำสั่ง Show Rendering แล้วเปลี่ยนตัวเลือกจำลองฟีเจอร์สื่อ CSS prefers-color-scheme

ภาพหน้าจอของตัวเลือก &quot;จำลองฟีเจอร์สื่อ CSS prefers-color-scheme&quot; ซึ่งอยู่ในแท็บการแสดงผลของเครื่องมือสําหรับนักพัฒนาเว็บใน Chrome

การจับภาพหน้าจอ prefers-color-scheme ด้วย Puppeteer

Puppeteer เป็นไลบรารี Node.js ที่ให้บริการ API ระดับสูงเพื่อควบคุม Chrome หรือ Chromium ผ่านโปรโตคอลเครื่องมือสำหรับนักพัฒนาซอฟต์แวร์ เมื่อใช้ dark-mode-screenshot เรามีสคริปต์ Puppeteer ที่ช่วยให้คุณสร้างภาพหน้าจอของหน้าเว็บทั้งในโหมดมืดและโหมดสว่างได้ คุณสามารถเรียกใช้สคริปต์นี้แบบครั้งเดียว หรือจะทําให้เป็นส่วนหนึ่งของชุดทดสอบการผสานรวมอย่างต่อเนื่อง (CI) ก็ได้

npx dark-mode-screenshot --url https://googlechromelabs.github.io/dark-mode-toggle/demo/ --output screenshot --fullPage --pause 750

แนวทางปฏิบัติแนะนำสำหรับโหมดมืด

หลีกเลี่ยงสีขาวล้วน

รายละเอียดเล็กๆ น้อยๆ ที่คุณอาจสังเกตเห็นคือเราไม่ได้ใช้สีขาวล้วน แต่เราเลือกสีขาวที่เข้มกว่าเล็กน้อยเพื่อป้องกันไม่ให้ข้อความเรืองแสงและเลอะเลือนกับเนื้อหาสีเข้มรอบๆ ตัวอย่างชื่อที่ใช้งานได้ดี เช่น rgb(250, 250, 250)

เปลี่ยนสีและทำให้รูปภาพมืดลง

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

รูปภาพหลักมืดลงเล็กน้อยในโหมดมืด
รูปภาพหลักในโหมดมืดมีความมืดกว่าเล็กน้อย
รูปภาพหลักปกติในโหมดสว่าง
รูปภาพหลักปกติในโหมดสว่าง

คุณสามารถเติมสีอีกครั้งผ่านฟิลเตอร์ CSS ในรูปภาพ เราใช้ตัวเลือก CSS ที่ตรงกับรูปภาพทั้งหมดที่ไม่มี .svg ใน URL โดยมีแนวคิดว่าเราสามารถเปลี่ยนสีกราฟิกเวกเตอร์ (ไอคอน) ต่างจากรูปภาพ (รูปถ่าย) ของเราได้ ดูข้อมูลเพิ่มเติมได้ในย่อหน้าถัดไป โปรดสังเกตว่าเราใช้ตัวแปร CSS อีกครั้งเพื่อให้เปลี่ยนตัวกรองได้อย่างยืดหยุ่นในภายหลัง

เนื่องจากจำเป็นต้องเปลี่ยนสีอีกครั้งในโหมดมืดเท่านั้น ซึ่งก็คือเมื่อ dark.css เปิดใช้งานอยู่ จึงไม่มีกฎที่เกี่ยวข้องใน light.css

/* dark.css */
--image-filter: grayscale(50%);

img:not([src*='.svg']) {
  filter: var(--image-filter);
}

การปรับแต่งความเข้มของการปรับสีโหมดมืดด้วย JavaScript

ผู้ใช้แต่ละคนมีความแตกต่างกันและต้องการโหมดมืดในลักษณะที่แตกต่างกัน เมื่อใช้วิธีการเปลี่ยนสีที่อธิบายไว้ข้างต้น ฉันสามารถทำให้ความเข้มของสีเทาเป็นค่ากำหนดของผู้ใช้ที่ฉันเปลี่ยนแปลงผ่าน JavaScript ได้อย่างง่ายดาย และการตั้งค่าเป็นค่า 0% ยังทำให้ฉันปิดใช้การเปลี่ยนสีได้ทั้งหมด โปรดทราบว่า document.documentElement มีการอ้างอิงองค์ประกอบรูทของเอกสาร ซึ่งเป็นองค์ประกอบเดียวกับที่ฉันอ้างอิงด้วยคลาสจำลอง :root CSS

const filter = 'grayscale(70%)';
document.documentElement.style.setProperty('--image-filter', value);

กลับภาพกราฟิกเวกเตอร์และไอคอน

สำหรับกราฟิกเวกเตอร์ ซึ่งในกรณีของฉันใช้เป็นไอคอนที่ฉันอ้างอิงผ่านองค์ประกอบ <img> ฉันจะใช้วิธีการเปลี่ยนสีอีกครั้งแบบอื่น แม้ว่าการวิจัยจะแสดงให้เห็นว่าผู้คนไม่ชอบการกลับสีสำหรับรูปภาพ แต่การกลับสีก็เหมาะกับไอคอนส่วนใหญ่ เราใช้ตัวแปร CSS อีกครั้งเพื่อกำหนดจำนวนการกลับค่าในสถานะปกติและ :hover

ไอคอนจะกลับสีในโหมดมืด
ไอคอนจะกลับสีในโหมดมืด
ไอคอนปกติในโหมดสว่าง
ไอคอนปกติในโหมดสว่าง

โปรดสังเกตอีกครั้งว่าฉันกลับสีไอคอนใน dark.css เท่านั้น แต่ไม่ได้กลับสีใน light.css และวิธีที่ :hover ได้รับระดับการกลับสีที่แตกต่างกันใน 2 กรณีนี้เพื่อให้ไอคอนดูเข้มขึ้นหรือสว่างขึ้นเล็กน้อย ทั้งนี้ขึ้นอยู่กับโหมดที่ผู้ใช้เลือก

/* dark.css */
--icon-filter: invert(100%);
--icon-filter_hover: invert(40%);

img[src*='.svg'] {
  filter: var(--icon-filter);
}
/* light.css */
--icon-filter_hover: invert(60%);
/* style.css */
img[src*='.svg']:hover {
  filter: var(--icon-filter_hover);
}

ใช้ currentColor สำหรับ SVG แทรกในบรรทัด

สำหรับรูปภาพ SVG ในบรรทัด คุณสามารถใช้คีย์เวิร์ด currentColor ของ CSS ที่แสดงค่าของพร็อพเพอร์ตี้ color ขององค์ประกอบแทนการใช้ฟิลเตอร์การกลับสี ซึ่งจะช่วยให้คุณใช้ค่า color ในพร็อพเพอร์ตี้ที่ไม่ได้รับค่าดังกล่าวโดยค่าเริ่มต้นได้ เพื่อความสะดวก หากใช้ currentColor เป็นค่าของแอตทริบิวต์ SVG fill หรือ stroke ระบบจะใช้ค่าจากค่าที่รับค่ามาของพร็อพเพอร์ตี้ color แทน ที่ดียิ่งขึ้นคือ รูปแบบนี้ยังใช้ได้กับ <svg><use href="…"></svg> ด้วย คุณจึงมีทรัพยากรแยกต่างหากได้ และ currentColor จะยังคงใช้ตามบริบท โปรดทราบว่าการดําเนินการนี้จะใช้ได้กับ SVG ในบรรทัดหรือ <use href="…"> เท่านั้น แต่จะใช้กับ SVG ที่อ้างอิงเป็น src ของรูปภาพหรือผ่าน CSS ไม่ได้ คุณจะเห็นการใช้งานนี้ในการสาธิตด้านล่าง

<!-- Some inline SVG -->
<svg xmlns="http://www.w3.org/2000/svg"
    stroke="currentColor"
>
  […]
</svg>

การเปลี่ยนโหมดอย่างราบรื่น

การเปลี่ยนจากโหมดมืดเป็นโหมดสว่างหรือในทางกลับกันจะราบรื่นขึ้นเนื่องจากทั้ง color และ background-color เป็นพร็อพเพอร์ตี้ CSS ที่เคลื่อนไหวได้ การสร้างภาพเคลื่อนไหวนั้นง่ายเพียงประกาศ transition 2 รายการสําหรับพร็อพเพอร์ตี้ 2 รายการ ตัวอย่างด้านล่างแสดงแนวคิดโดยรวม คุณสามารถทดลองใช้แบบเรียลไทม์ในเดโม

body {
  --duration: 0.5s;
  --timing: ease;

  color: var(--color);
  background-color: var(--background-color);

  transition: color var(--duration) var(--timing), background-color var(
        --duration
      ) var(--timing);
}

กำกับศิลป์ด้วยโหมดมืด

แม้ว่าโดยทั่วไปแล้วเราจะแนะนำให้ใช้ prefers-color-scheme ในแอตทริบิวต์ media ขององค์ประกอบ <link> เท่านั้น (แทนที่จะแทรกในสไตล์ชีต) เพื่อเหตุผลด้านประสิทธิภาพในการโหลด แต่ก็มีบางกรณีที่คุณอาจต้องใช้งาน prefers-color-scheme ในโค้ด HTML โดยตรง การจัดอาร์ตเวิร์กก็เป็นเช่นนั้น บนเว็บ ฝ่ายศิลป์ดูแลภาพรวมของหน้าเว็บและวิธีสื่อสารด้วยภาพ กระตุ้นอารมณ์ ตัดกันด้วยฟีเจอร์ต่างๆ และดึงดูดกลุ่มเป้าหมายทางจิตวิทยา

สำหรับโหมดมืด ขึ้นอยู่กับวิจารณญาณของนักออกแบบว่าจะเลือกรูปภาพใดให้เหมาะกับโหมดนั้นๆ มากที่สุด และการปรับสีรูปภาพอาจไม่เหมาะหรือไม่ หากใช้กับองค์ประกอบ <picture> คุณสามารถทำให้ <source> ของรูปภาพที่แสดงขึ้นอยู่กับแอตทริบิวต์ media ได้ ในตัวอย่างด้านล่างนี้ เราแสดงซีกโลกตะวันตกสำหรับโหมดมืด และซีกโลกตะวันออกสำหรับโหมดสว่าง หรือในกรณีที่ไม่มีค่ากำหนด ระบบจะใช้ซีกโลกตะวันออกเป็นค่าเริ่มต้นสำหรับกรณีอื่นๆ ทั้งหมด แน่นอนว่าภาพนี้เป็นเพียงภาพประกอบเท่านั้น สลับโหมดมืดในอุปกรณ์เพื่อดูความแตกต่าง

<picture>
  <source srcset="western.webp" media="(prefers-color-scheme: dark)" />
  <source srcset="eastern.webp" media="(prefers-color-scheme: light)" />
  <img src="eastern.webp" />
</picture>

โหมดมืด แต่เพิ่มตัวเลือกในการเลือกไม่ใช้

ดังที่ได้กล่าวไว้ในส่วนเหตุผลที่ควรใช้โหมดมืดข้างต้น โหมดมืดเป็นตัวเลือกที่ผู้ใช้ส่วนใหญ่ชื่นชอบ ด้วยเหตุนี้ ผู้ใช้บางรายอาจชอบให้ UI ของระบบปฏิบัติการเป็นโหมดมืด แต่ยังคงต้องการดูหน้าเว็บในแบบที่ตนคุ้นเคย รูปแบบที่ยอดเยี่ยมคือยึดตามสัญญาณที่เบราว์เซอร์ส่งผ่าน prefers-color-scheme ในตอนแรก แต่อนุญาตให้ผู้ใช้ลบล้างการตั้งค่าระดับระบบได้ (ไม่บังคับ)

องค์ประกอบที่กำหนดเอง <dark-mode-toggle>

แน่นอนว่าคุณสร้างโค้ดนี้ด้วยตนเองได้ แต่คุณก็ใช้องค์ประกอบที่กําหนดเอง (คอมโพเนนต์เว็บ) ที่พร้อมใช้งานซึ่งเราสร้างมาเพื่อวัตถุประสงค์นี้โดยเฉพาะก็ได้ ฟีเจอร์นี้มีชื่อว่า <dark-mode-toggle> และเพิ่มปุ่มเปิด/ปิด (โหมดมืด: เปิด/ปิด) หรือปุ่มสลับธีม (ธีม: สว่าง/มืด) ลงในหน้าเว็บที่คุณปรับแต่งได้อย่างเต็มที่ ตัวอย่างด้านล่างแสดงองค์ประกอบที่ทำงานอยู่ (และเราก็ได้แอบใส่องค์ประกอบนี้ไว้ในตัวอย่าง อื่นๆ ทั้งหมดข้างต้นด้วย)

<dark-mode-toggle
  legend="Theme Switcher"
  appearance="switch"
  dark="Dark"
  light="Light"
  remember="Remember this"
></dark-mode-toggle>
dark-mode-toggle ในโหมดสว่าง
<dark-mode-toggle> ในโหมดสว่าง
dark-mode-toggle ในโหมดสว่าง
<dark-mode-toggle> ในโหมดมืด

ลองคลิกหรือแตะตัวควบคุมโหมดมืดที่มุมขวาบนในการแสดงตัวอย่างด้านล่าง หากคุณเลือกช่องทําเครื่องหมายในการควบคุมที่ 3 และ 4 ให้ดูว่าระบบจดจําการเลือกโหมดของคุณอย่างไรแม้ว่าคุณจะโหลดหน้าเว็บซ้ำ ซึ่งจะช่วยให้ผู้เข้าชมใช้ระบบปฏิบัติการในโหมดมืดได้อยู่เสมอ แต่เพลิดเพลินกับเว็บไซต์ในโหมดสว่างได้ หรือในทางกลับกัน

สรุป

การทำงานและรองรับโหมดมืดเป็นเรื่องสนุกและเปิดโอกาสใหม่ๆ ให้กับการออกแบบ สำหรับผู้เข้าชมบางราย การมีตัวเลือกนี้อาจหมายถึงความแตกต่างระหว่างการไม่สามารถใช้งานเว็บไซต์ของคุณกับการเป็นผู้ใช้ที่มีความสุข แน่นอนว่ามีข้อผิดพลาดบางประการและต้องมีการทดสอบอย่างละเอียดรอบคอบ แต่โหมดมืดเป็นโอกาสที่ดีในการแสดงให้เห็นว่าคุณใส่ใจผู้ใช้ทุกคน แนวทางปฏิบัติแนะนำที่กล่าวถึงในโพสต์นี้และเครื่องมือช่วยเหลือ เช่น องค์ประกอบที่กำหนดเอง <dark-mode-toggle> ควรช่วยให้คุณมั่นใจในความสามารถที่จะสร้างประสบการณ์การใช้งานโหมดมืดที่ยอดเยี่ยม บอกให้เราทราบใน Twitter ว่าคุณสร้างอะไรและโพสต์นี้มีประโยชน์หรือไม่ หรือมีคำแนะนำในการปรับปรุง ขอขอบคุณที่อ่าน 🌒

แหล่งข้อมูลสําหรับคิวรีสื่อ prefers-color-scheme

แหล่งข้อมูลสำหรับเมตาแท็ก color-scheme และพร็อพเพอร์ตี้ CSS

ลิงก์ทั่วไปสำหรับโหมดมืด

บทความสําหรับการค้นคว้าข้อมูลเบื้องต้นสําหรับโพสต์นี้

ขอขอบคุณ

ฟีเจอร์สื่อ prefers-color-scheme, พร็อพเพอร์ตี้ CSS color-scheme และเมตาแท็กที่เกี่ยวข้องเป็นงานติดตั้งใช้งานของ 👏 Rune Lillesveen Rune ยังเป็นผู้ร่วมแก้ไขข้อกำหนดของข้อบังคับระดับ 1 ของโมดูลการปรับสี CSS ด้วย และขอขอบคุณ Lukasz Zbylut, Rowan Merewood, Chirag Desai และ Rob Dodson ที่ตรวจสอบบทความนี้อย่างละเอียด กลยุทธ์การโหลดเป็นแนวคิดของ Jake Archibald Emilio Cobos Álvarez ได้ชี้แนะวิธีการตรวจหา prefers-color-scheme ที่ถูกต้อง เคล็ดลับที่มี SVG ที่อ้างอิงและ currentColor มาจาก Timothy Hatcher สุดท้ายนี้ เราขอขอบคุณผู้เข้าร่วมที่ไม่ประสงค์ออกนามจำนวนมากในการศึกษาผู้ใช้ต่างๆ ที่ช่วยให้คำแนะนำในบทความนี้เป็นรูปเป็นร่าง รูปภาพหลักโดย Nathan Anderson