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

พร็อพเพอร์ตี้ CSS color-scheme และเมตาแท็กที่เกี่ยวข้องช่วยให้นักพัฒนาแอปเลือกให้หน้าเว็บใช้สไตล์ชีต User Agent เริ่มต้นเฉพาะธีมได้

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

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

การสนับสนุนเบราว์เซอร์

prefers-color-scheme

การรองรับเบราว์เซอร์

  • Chrome: 76
  • Edge: 79
  • Firefox: 67
  • Safari: 12.1

แหล่งที่มา

color-scheme

การรองรับเบราว์เซอร์

  • Chrome: 81
  • Edge: 81
  • Firefox: 96
  • Safari: 13.

แหล่งที่มา

สไตล์ชีต User Agent

ก่อนจะไปต่อ เราขออธิบายสั้นๆ ว่าสไตล์ชีต User Agent คืออะไร โดยปกติแล้ว คุณอาจคิดว่าคำว่า User Agent (UA) เป็นคำพูดที่เก๋ไก๋สำหรับเบราว์เซอร์ สไตล์ชีต UA จะกําหนดลักษณะและอารมณ์เริ่มต้นของหน้าเว็บ ดังที่ชื่อบอกไว้ สไตล์ชีต UA คือสิ่งที่ขึ้นอยู่กับ UA ที่เป็นปัญหา คุณสามารถดูสไตล์ชีต UA ของChrome (และ Chromium) และเปรียบเทียบกับของFirefox หรือSafari (และ WebKit) โดยทั่วไปแล้ว สไตล์ชีต UA จะตรงกันในเรื่องส่วนใหญ่ เช่น เว็บไซต์ทั้งหมดใช้ลิงก์สีน้ำเงิน ข้อความทั่วไปสีดํา และพื้นหลังสีขาว แต่ก็มีความแตกต่างที่สําคัญ (และบางครั้งก็น่ารําคาญ) เช่น การจัดรูปแบบตัวควบคุมแบบฟอร์ม

ดูรายละเอียดของสไตล์ชีต UA ของ WebKit และสิ่งที่ทําเกี่ยวกับโหมดมืด (ค้นหาข้อความ "dark" แบบเต็มในสไตล์ชีต) ค่าเริ่มต้นที่ได้จากสไตล์ชีตจะเปลี่ยนแปลงตามสถานะเปิดหรือปิดโหมดมืด ต่อไปนี้เป็นตัวอย่างกฎ CSS ที่ใช้คลาสจำลอง :matches และตัวแปรภายใน WebKit เช่น -apple-system-control-background รวมถึงคำสั่งของโปรแกรมประมวลผลข้อมูลล่วงหน้าภายใน WebKit อย่าง #if defined

input,
input:matches([type="password"], [type="search"]) {
  -webkit-appearance: textfield;
  #if defined(HAVE_OS_DARK_MODE_SUPPORT) &&
      HAVE_OS_DARK_MODE_SUPPORT
    color: text;
    background-color: -apple-system-control-background;
  #else
    background-color: white;
  #endif
  /* snip */
}

คุณจะเห็นค่าที่ไม่เป็นไปตามมาตรฐานสำหรับพร็อพเพอร์ตี้ color และ background-color ด้านบน ทั้ง text และ -apple-system-control-background ไม่ใช่สี CSS ที่ถูกต้อง ซึ่งเป็นสีเชิงความหมายภายใน WebKit

แต่ CSS มีสีของระบบตามความหมายที่เป็นมาตรฐาน ซึ่งระบุไว้ในโมดูลสี CSS ระดับ 4 ตัวอย่างเช่น Canvas (อย่าสับสนกับแท็ก <canvas>) ใช้สำหรับพื้นหลังของเนื้อหาหรือเอกสารแอปพลิเคชัน ส่วน CanvasText ใช้สำหรับข้อความในเนื้อหาหรือเอกสารแอปพลิเคชัน 2 รายการนี้ใช้ร่วมกันได้และไม่ควรใช้แยกกัน

สไตล์ชีต UA สามารถใช้สีที่เป็นกรรมสิทธิ์ของตนเองหรือสีของระบบตามหลักการจัดหมวดหมู่ที่เป็นมาตรฐานเพื่อกำหนดวิธีแสดงผลองค์ประกอบ HTML โดยค่าเริ่มต้น หากระบบปฏิบัติการตั้งค่าเป็นโหมดมืดหรือใช้ธีมมืด ระบบจะตั้งค่า CanvasText (หรือ text) เป็นสีขาวแบบมีเงื่อนไข และตั้งค่า Canvas (หรือ -apple-system-control-background) เป็นสีดํา จากนั้นสไตลชีต UA จะกําหนด CSS ต่อไปนี้เพียงครั้งเดียว และครอบคลุมทั้งโหมดสว่างและโหมดมืด

/**
  Not actual UA stylesheet code.
  For illustrative purposes only.
*/
body {
  color: CanvasText;
  background-color: Canvas
}

พร็อพเพอร์ตี้ CSS color-scheme

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

พร็อพเพอร์ตี้ color-scheme ที่กําหนดไว้ช่วยให้องค์ประกอบระบุรูปแบบสีที่แสดงผลได้ ค่าเหล่านี้จะเจรจาต่อรองกับค่ากําหนดของผู้ใช้ ซึ่งจะส่งผลให้ได้รูปแบบสีที่เลือกซึ่งส่งผลต่อสิ่งต่างๆ ในอินเทอร์เฟซผู้ใช้ (UI) เช่น สีเริ่มต้นของการควบคุมแบบฟอร์มและแถบเลื่อน รวมถึงค่าที่ใช้สำหรับสีของระบบ CSS ปัจจุบันระบบรองรับค่าต่อไปนี้

  • normal บ่งบอกว่าองค์ประกอบไม่รับรู้รูปแบบสีเลย ดังนั้นองค์ประกอบควรแสดงผลด้วยรูปแบบสีเริ่มต้นของเบราว์เซอร์

  • [ light | dark ]+ บ่งบอกว่าองค์ประกอบรับรู้และจัดการรูปแบบสีที่ระบุได้ และแสดงค่ากำหนดตามลําดับระหว่างรูปแบบสีเหล่านั้น

ในรายการนี้ light แสดงถึงรูปแบบสีอ่อน ซึ่งมีสีพื้นหลังอ่อนและสีพื้นหน้าเข้ม ส่วน dark แสดงถึงรูปแบบสีตรงข้ามกัน ซึ่งมีสีพื้นหลังเข้มและสีพื้นหน้าอ่อน

สำหรับองค์ประกอบทั้งหมด การแสดงผลด้วยรูปแบบสีควรทําให้สีที่ใช้ใน UI ทั้งหมดที่เบราว์เซอร์ให้ไว้สําหรับองค์ประกอบนั้นตรงกับเจตนาของรูปแบบสี เช่น แถบเลื่อน ขีดใต้เพื่อตรวจตัวสะกด ตัวควบคุมแบบฟอร์ม ฯลฯ

ในองค์ประกอบ :root การแสดงผลด้วยรูปแบบสีจะต้องส่งผลต่อสีพื้นผิวของผืนผ้าใบ (นั่นคือสีพื้นหลังส่วนกลาง) ค่าเริ่มต้นของพร็อพเพอร์ตี้ color และค่าที่ใช้ของสีของระบบ และควรส่งผลต่อแถบเลื่อนของวิวพอร์ตด้วย

/*
  The page supports both dark and light color schemes,
  and the page author prefers dark.
*/
:root {
  color-scheme: dark light;
}

เมตาแท็ก color-scheme

การปฏิบัติตามพร็อพเพอร์ตี้ CSS color-scheme กำหนดให้ต้องดาวน์โหลด CSS ก่อน (หากมีการอ้างอิงผ่าน <link rel="stylesheet">) และทำการแยกวิเคราะห์ คุณระบุค่า color-scheme ในองค์ประกอบ <meta name="color-scheme"> ได้เช่นกันเพื่อช่วย User Agent ในการเรนเดอร์พื้นหลังของหน้าเว็บด้วยรูปแบบสีที่ต้องการทันที

<!--
  The page supports both dark and light color schemes,
  and the page author prefers dark.
-->
<meta name="color-scheme" content="dark light">

การรวม color-scheme และ prefers-color-scheme

เนื่องจากทั้งเมตาแท็กและพร็อพเพอร์ตี้ CSS (หากใช้กับองค์ประกอบ :root) จะให้ผลลัพธ์เหมือนกัน เราจึงขอแนะนำให้ระบุรูปแบบสีผ่านเมตาแท็กเสมอ เพื่อให้เบราว์เซอร์ใช้รูปแบบที่ต้องการได้เร็วขึ้น

แม้ว่าหน้าฐานบรรทัดฐานสัมบูรณ์จะไม่ต้องใช้กฎ CSS เพิ่มเติม แต่ในกรณีทั่วไป คุณควรรวม color-scheme เข้ากับ prefers-color-scheme เสมอ ตัวอย่างเช่น สี -webkit-link ใน CSS ของ WebKit ซึ่งเป็นกรรมสิทธิ์ ซึ่ง WebKit และ Chrome ใช้สำหรับสีน้ำเงินแบบคลาสสิกของลิงก์ rgb(0,0,238) มีสัดส่วนคอนทราสต์ 2.23:1 ซึ่งไม่เพียงพอเมื่อใช้กับพื้นหลังสีดํา และไม่ผ่านทั้งข้อกําหนดของ WCAG AA และ WCAG AAA

เราได้เปิดข้อบกพร่องสำหรับ Chrome, WebKit และ Firefox รวมถึงปัญหาเกี่ยวกับเมตาในมาตรฐาน HTML เพื่อแก้ไขปัญหานี้

โต้ตอบกับ prefers-color-scheme

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

<head>
  <meta name="color-scheme" content="dark light">
  <style>
    fieldset {
      background-color: gainsboro;
    }
    @media (prefers-color-scheme: dark) {
      fieldset {
        background-color: darkslategray;
      }
    }
  </style>
</head>
<body>
  <p>
    Lorem ipsum dolor sit amet, legere ancillae ne vis.
  </p>
  <form>
    <fieldset>
      <legend>Lorem ipsum</legend>
      <button type="button">Lorem ipsum</button>
    </fieldset>
  </form>
</body>

โค้ด CSS ในบรรทัดบนหน้าเว็บจะตั้งค่า background-color ขององค์ประกอบ <fieldset> เป็น gainsboro ในกรณีทั่วไป และตั้งค่าเป็น darkslategray หากผู้ใช้ต้องการใช้ชุดค่าผสมสี dark ตามฟีเจอร์สื่อค่ากำหนดของผู้ใช้ prefers-color-scheme

หน้าเว็บจะบอกเบราว์เซอร์ผ่านองค์ประกอบ <meta name="color-scheme" content="dark light"> ว่ารองรับธีมมืดและธีมสว่าง โดยระบุค่ากําหนดเป็นธีมมืด

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

โปรดสังเกตว่า background-color ขององค์ประกอบ <fieldset> เปลี่ยนแปลงอย่างไร โดยอิงตามการเปิดใช้โหมดมืดหรือไม่ เป็นไปตามกฎในสไตล์ชีตแบบแทรกในหน้าเว็บที่นักพัฒนาซอฟต์แวร์ระบุ gainsboro หรือ darkslategray

หน้าเว็บในโหมดสว่าง
โหมดสว่าง: รูปแบบที่นักพัฒนาแอปและ User Agent ระบุ ข้อความเป็นสีดําและพื้นหลังเป็นสีขาวตามสไตล์ชีตของ User Agent background-color ขององค์ประกอบ <fieldset> คือ gainsboro ตามสไตล์ชีตของนักพัฒนาแอปที่ฝังไว้
หน้าเว็บในโหมดมืด
โหมดมืด: รูปแบบที่นักพัฒนาแอปและ User Agent ระบุ ข้อความเป็นสีขาวและพื้นหลังเป็นสีดําตามสไตล์ชีตของ User Agent background-color ขององค์ประกอบ <fieldset> คือ darkslategray ตามสไตล์ชีตของนักพัฒนาแอปที่ฝังไว้

ลักษณะที่ปรากฏขององค์ประกอบ <button> ควบคุมโดยสไตล์ชีต User Agent color ของอุปกรณ์ตั้งค่าเป็นสีของระบบ ButtonText ส่วน background-color และ border-color 4 ตัวตั้งค่าเป็นสีของระบบ ButtonFace

หน้าโหมดสว่างที่ใช้พร็อพเพอร์ตี้ ButtonFace
โหมดสว่าง: background-color และ border-color ต่างๆ ได้รับการตั้งค่าเป็นสีของระบบ ButtonFace

ตอนนี้ให้สังเกตว่า border-color ขององค์ประกอบ <button> เปลี่ยนแปลงอย่างไร ค่าที่คำนวณแล้วสำหรับ border-top-color และ border-bottom-color จะเปลี่ยนจาก rgba(0, 0, 0, 0.847) (สีดำ) เป็น rgba(255, 255, 255, 0.847) (สีขาว) เนื่องจาก User Agent จะอัปเดต ButtonFace แบบไดนามิกตามรูปแบบสี เช่นเดียวกับ color ขององค์ประกอบ <button> ที่กําหนดเป็นสีของระบบ ButtonText ที่เกี่ยวข้อง

แสดงว่าค่าสีที่คำนวณแล้วตรงกับ ButtonFace
โหมดสว่าง: ค่าที่คำนวณแล้วของ border-top-color และ border-bottom-color ซึ่งตั้งค่าไว้เป็น ButtonFace ในสไตล์ชีต User Agent เปลี่ยนเป็น rgba(0, 0, 0, 0.847)
แสดงให้เห็นว่าค่าสีที่คำนวณยังคงตรงกับ ButtonFace ขณะอยู่ในโหมดมืด
โหมดมืด: ค่าที่คำนวณแล้วของ border-top-color และ border-bottom-color ซึ่งทั้ง 2 ค่าตั้งค่าเป็น ButtonFace ในสไตล์ชีต User Agent เปลี่ยนเป็น rgba(255, 255, 255, 0.847) แล้ว

สาธิต

คุณดูผลของ color-scheme ที่มีต่อองค์ประกอบ HTML จํานวนมากได้ในเดโมบน Glitch เดโมจงใจแสดงการละเมิด WCAG AA และ WCAG AAA ด้วยสีลิงก์ที่กล่าวถึงในคำเตือนด้านบน

การสาธิตขณะอยู่ในโหมดสว่าง
demo สลับเป็น color-scheme: light
การสาธิตขณะอยู่ในโหมดมืด
demo สลับเป็น color-scheme: dark โปรดทราบว่าการละเมิด WCAG AA และ WCAG AAA เกี่ยวข้องกับสีของลิงก์

ขอขอบคุณ

Rune Lillesveen เป็นผู้ติดตั้งใช้งานพร็อพเพอร์ตี้ CSS color-scheme และเมตาแท็กที่เกี่ยวข้อง Rune ยังเป็นผู้ร่วมแก้ไขข้อกำหนดระดับ 1 ของข้อบังคับเกี่ยวกับการปรับสี CSS ด้วย รูปภาพหลักโดย Philippe Leone จาก Unsplash