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

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

เกริ่นนำ

ใช้โหมดมืดก่อนโหมดมืด

จอคอมพิวเตอร์สีเขียว
Green Screen (แหล่งที่มา)

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

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

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

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

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

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

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

ทำไมต้องใช้โหมดมืด

ใช้โหมดมืดเพื่อเหตุผลด้านความสวยงาม

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

Close View ในระบบ Mac OS 7 ที่มี
ระบบ 7 CloseView (แหล่งที่มา)

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

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

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

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

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

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

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

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

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

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 สําหรับเบราว์เซอร์อื่นๆ ทั้งหมด ให้เลือกฉันใช้ตารางการสนับสนุนได้หรือไม่

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

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

โหมดมืดในสถานการณ์จริง

เรามาลองดูตัวอย่างการรองรับโหมดมืดในทางปฏิบัติกัน เช่นเดียวกับ Highlander โหมดมืดมีโหมดมืดได้เพียงโหมดเดียวคือ "มืด" หรือ "สว่าง" แต่เป็นทั้ง 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.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 ทั่วไปของฉันเป็นแบบทั่วไป และการปรับแต่งโหมดสว่างหรือมืดทั้งหมดจะเกิดขึ้นในไฟล์ dark.css และ light.css อื่นๆ อีก 2 ไฟล์ ด้านล่างนี้เป็นส่วนต่างๆ ที่ตัดตอนมาของสไตล์จริง แต่ก็เพียงพอที่จะสื่อถึงแนวคิดโดยรวมได้ ฉันประกาศตัวแปร 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 { … } ดังที่กําหนดไว้ในคลาส Pseudo ของ CSS ของ :root ซึ่งเป็นตัวเลือกที่ใน 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 สำหรับสิ่งที่สำคัญในเว็บไซต์ของฉัน การจัดระเบียบสไตล์เชิงความหมายมีประโยชน์มากเมื่อใช้โหมดมืด เช่น ลองเรียกตัวแปร -⁠-⁠accent-color แทน -⁠-⁠highlight-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);
}

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

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

กำลังโหลดผลกระทบ

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

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

รีแอ็กชันในโหมดมืดมีการเปลี่ยนแปลง

คุณติดตามการเปลี่ยนแปลงโหมดมืดผ่านทาง JavaScript ได้ เช่นเดียวกับการเปลี่ยนแปลงคิวรี่สื่ออื่นๆ คุณสามารถใช้การตั้งค่านี้เพื่อเปลี่ยน ไอคอน Fav ของหน้าเว็บแบบไดนามิก หรือเปลี่ยน <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

<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 DevTools จึงช่วยให้คุณจำลองรูปแบบสีที่ผู้ใช้ต้องการได้ในลักษณะที่ส่งผลต่อแท็บที่มองเห็นได้ในปัจจุบันเท่านั้น เปิดเมนูคำสั่ง จากนั้นเริ่มพิมพ์ Rendering เรียกใช้คำสั่ง Show Rendering แล้วเปลี่ยนตัวเลือก Emulate CSS media featurerefers-color-scheme

ภาพหน้าจอของตัวเลือก &quot;จำลองฟีเจอร์สื่อ CSS &quot;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 คลาส Pseudo-class ได้

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