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

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

บทนำ

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

คอมพิวเตอร์รุ่นเก่าก่อนยุค 90 แสดงข้อความสีเขียวบนพื้นหลังสีดำ
กรีนสกรีน (แหล่งที่มา)

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

จอภาพแสดง Microsoft Word เวอร์ชัน Windows 3.1
ข้อความสีเข้มบนพื้นหลังสีขาว (แหล่งที่มา)

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

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

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

โทรศัพท์มือถือที่ใช้บนเตียง

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

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

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

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

CloseView ในระบบ Mac OS 7 ที่มีโหมด "ข้อความสีขาวบนพื้นหลังสีดำ" (แหล่งที่มา)

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

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

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

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

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

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

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

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

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

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

prefers-color-scheme การค้นหาสื่อ

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

คุณติดตามการเปลี่ยนแปลงโหมดมืดได้ผ่าน JavaScript เช่นเดียวกับการเปลี่ยนแปลง Media Query อื่นๆ คุณสามารถใช้สิ่งนี้เพื่อเปลี่ยน 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 ขององค์ประกอบสีธีม meta ระบบจะเลือกรายการแรกที่ตรงกัน เช่น คุณอาจมีสีหนึ่งสำหรับ โหมดสว่างและอีกสีหนึ่งสำหรับโหมดมืด ในขณะที่เขียนนี้ คุณไม่สามารถ กำหนดค่าเหล่านั้นในไฟล์ Manifest ได้ ดู w3c/manifest#975 GitHub issue

<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 ผ่านโปรโตคอล DevTools 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 ในบรรทัด คุณสามารถใช้คีย์เวิร์ด CSS currentColor แทนการใช้ฟิลเตอร์การกลับสี ซึ่งแสดงค่าของพร็อพเพอร์ตี้ color ขององค์ประกอบ ซึ่งจะช่วยให้คุณใช้ค่า color ในพร็อพเพอร์ตี้ที่ไม่ได้รับค่าดังกล่าวโดยค่าเริ่มต้นได้ หากใช้ currentColor เป็นค่าของแอตทริบิวต์ SVG fill หรือ stroke ระบบจะใช้ค่าจากค่าที่รับช่วงของพร็อพเพอร์ตี้สีแทน และที่ดียิ่งกว่าคือฟีเจอร์นี้ยังใช้ได้กับ <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> ในโหมดมืด

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

บทสรุป

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

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

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

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

บทความการวิจัยเบื้องหลังสำหรับโพสต์นี้

คำขอบคุณ

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