Preferreds-color-scheme: Xin chào bóng tối, bạn cũ của tôi

Quá phóng đại hay cần thiết? Tìm hiểu mọi thứ về chế độ tối và cách hỗ trợ chế độ này vì lợi ích của người dùng!

Giới thiệu

Chế độ tối trước Chế độ tối

Màn hình máy tính có màn hình xanh lục
Màn hình xanh lục (Nguồn)

Chúng ta đã chuyển sang chế độ tối. Ở thời kỳ ban đầu của điện toán cá nhân, chế độ tối không phải là sự lựa chọn, mà là một vấn đề thực tế: Màn hình máy tính CRT đơn sắc hoạt động bằng cách bắn ra các tia điện tử trên màn hình phát quang và phốt pho được sử dụng trong các CRT đời đầu có màu xanh lục. Vì văn bản hiển thị bằng màu xanh lục và phần còn lại của màn hình là màu đen, nên những mô hình này thường được gọi là màn hình màu xanh lục.

Xử lý văn bản đen trắng
Màu trắng đậm (Nguồn)

Các CRT màu được giới thiệu sau đó sẽ hiển thị nhiều màu sắc thông qua việc sử dụng phốt pho màu đỏ, xanh lục và xanh dương. Họ tạo ra màu trắng bằng cách kích hoạt đồng thời cả ba loại phốt pho này. Với sự ra đời của WYSIWYG chế độ xuất bản trên máy tính tinh vi hơn, ý tưởng làm cho tài liệu ảo giống với một trang giấy thực trở nên phổ biến.

Trang web có màu trắng tối trên trình duyệt WorldwideWeb
Trình duyệt WorldwideWeb (Nguồn)

Đây là nơi xu hướng thiết kế màu trắng đen bắt đầu, và xu hướng này đã được chuyển sang môi trường web dựa trên tài liệu ban đầu. Trình duyệt đầu tiên, WorldWideWeb (hãy nhớ rằng CSS thậm chí chưa được phát minh), hiển thị trang web theo cách này. Sự thật thú vị: trình duyệt thứ hai từ trước đến nay, Trình duyệt chế độ dòng (một trình duyệt dựa trên thiết bị đầu cuối) có màu xanh lục trên nền tối. Ngày nay, các trang web và ứng dụng web thường được thiết kế với văn bản tối trên nền sáng. Đây là giả định cơ sở cũng được mã hoá cứng trong biểu định kiểu tác nhân người dùng, bao gồm cả của Chrome.

Điện thoại thông minh được dùng khi nằm trên giường
Điện thoại thông minh dùng trên giường (Nguồn: Unsplash)

Thời gian sử dụng CRT đã qua rồi. Việc tiêu thụ và sáng tạo nội dung đã chuyển sang các thiết bị di động sử dụng màn hình LCD có đèn nền hoặc màn hình AMOLED tiết kiệm năng lượng. Máy tính, máy tính bảng và điện thoại thông minh nhỏ hơn và dễ di chuyển hơn đã dẫn đến các thói quen sử dụng mới. Các công việc giải trí như duyệt web, lập trình để giải trí và chơi trò chơi cao cấp thường diễn ra sau giờ làm việc trong môi trường thiếu sáng. Mọi người thậm chí còn tận hưởng thiết bị trên giường vào ban đêm. Mọi người càng sử dụng thiết bị trong bóng tối, thì ý tưởng quay về nguồn gốc của chế độ sáng tối càng trở nên phổ biến.

Lý do nên sử dụng chế độ tối

Chế độ tối để tăng tính thẩm mỹ

Khi mọi người được hỏi lý do họ thích hay muốn sử dụng chế độ tối, câu trả lời phổ biến nhất là "để mắt dễ nhìn hơn", sau đó là "trang nhã và đẹp mắt". Apple trong tài liệu dành cho nhà phát triển về Chế độ tối có viết rõ ràng: "Việc lựa chọn hiển thị giao diện sáng hay tối sẽ mang lại tính thẩm mỹ cho hầu hết người dùng và có thể không liên quan đến điều kiện ánh sáng xung quanh".

CloseView trong Hệ thống Mac OS 7 với
System 7 CloseView (Nguồn)

Chế độ tối là công cụ hỗ trợ tiếp cận

Ngoài ra, có những người thực sự cần có chế độ tối và sử dụng chế độ này như một công cụ hỗ trợ tiếp cận khác, chẳng hạn như người dùng có thị lực kém. Công cụ hỗ trợ tiếp cận như vậy xuất hiện sớm nhất là tính năng CloseView của System 7, có nút bật/tắt Đen trên trắngTrắng trên đen. Mặc dù màu Hệ thống 7 hỗ trợ nhưng giao diện người dùng mặc định vẫn là màu đen trắng.

Những phương pháp triển khai dựa trên đảo ngược này đã bộc lộ điểm yếu khi xuất hiện màu sắc. Nghiên cứu về người dùng của Szpiro và cộng sự về cách những người có thiết bị điện toán có thị lực kém cho thấy rằng tất cả những người dùng được phỏng vấn đều không thích hình ảnh đảo ngược, nhưng nhiều người lại thích văn bản sáng hơn trên nền tối. Apple đáp ứng lựa chọn ưu tiên này của người dùng bằng một tính năng có tên Smart Invert (Đảo ngược thông minh), giúp đảo ngược các màu trên màn hình, ngoại trừ hình ảnh, nội dung nghe nhìn và một số ứng dụng sử dụng kiểu màu tối.

Một dạng đặc biệt của thị lực kém là Hội chứng thị giác máy tính, hay còn gọi là Căng mắt kỹ thuật số, được định nghĩa"sự kết hợp của các vấn đề về mắt và thị lực liên quan đến việc sử dụng máy tính (bao gồm máy tính để bàn, máy tính xách tay và máy tính bảng) và các màn hình điện tử khác (ví dụ: điện thoại thông minh và thiết bị đọc điện tử)." Nó đã được đề xuất rằng việc thanh thiếu niên sử dụng thiết bị điện tử, đặc biệt là vào ban đêm, dẫn đến nguy cơ tăng thời lượng giấc ngủ ngắn hơn, thời gian chờ khởi động giấc ngủ dài hơn và tăng tình trạng thiếu ngủ. Ngoài ra, việc tiếp xúc với ánh sáng xanh đã được báo cáo rộng rãi có liên quan đến việc điều chỉnh nhịp sinh học và chu kỳ ngủ. Ngoài ra, môi trường ánh sáng bất thường có thể dẫn đến thiếu ngủ, có thể ảnh hưởng đến tâm trạng và hiệu suất công việc, theo nghiên cứu của Rosenfield. Để hạn chế các tác động tiêu cực này, hãy giảm ánh sáng xanh dương bằng cách điều chỉnh nhiệt độ màu của màn hình thông qua các tính năng như Night Shift của iOS hoặc Ánh sáng đêm của Android, cũng như tránh ánh sáng chói hoặc ánh sáng không đều nói chung thông qua giao diện tối hoặc chế độ tối.

Tiết kiệm điện năng ở chế độ tối trên màn hình AMOLED

Cuối cùng, chế độ tối được biết đến là giúp tiết kiệm nhiều năng lượng trên màn hình AMOLED. Các nghiên cứu điển hình về Android tập trung vào các ứng dụng phổ biến của Google như YouTube đã chỉ ra rằng mức tiết kiệm pin có thể lên tới 60%. Video dưới đây cung cấp thêm thông tin về các nghiên cứu điển hình này và mức tiết kiệm pin cho mỗi ứng dụng.

Đang kích hoạt chế độ tối trong hệ điều hành

Vậy là tôi đã trình bày lý do chế độ tối là một vấn đề lớn đối với nhiều người dùng, hãy cùng xem xét cách hỗ trợ chế độ tối.

Cài đặt chế độ tối của Android Q
Chế độ cài đặt giao diện tối của Android Q

Các hệ điều hành hỗ trợ chế độ tối hoặc giao diện tối thường có tuỳ chọn kích hoạt chế độ này ở đâu đó trong phần cài đặt. Trên macOS X, biểu tượng này nằm trong phần General (Chung) của tuỳ chọn hệ thống và được gọi là Appearance (ảnh chụp màn hình). Còn trên Windows 10, tuỳ chọn này nằm trong phần Colors (Màu sắc) và có tên Choose your color (Chọn màu) (ảnh chụp màn hình). Đối với Android Q, bạn có thể tìm thấy biểu tượng này trong mục Display (Màn hình) dưới dạng công tắc bật/tắt Dark Theme (Giao diện tối) (ảnh chụp màn hình) và trên iOS 13, bạn có thể thay đổi Appearance (Giao diện) trong phần Display & Mang (Màn hình và độ sáng) của phần cài đặt (ảnh chụp màn hình).

Truy vấn phương tiện prefers-color-scheme

Đây là một phần lý thuyết cuối cùng trước khi tôi bắt đầu. Truy vấn nội dung nghe nhìn cho phép tác giả kiểm thử và truy vấn các giá trị hoặc tính năng của tác nhân người dùng hoặc thiết bị hiển thị, độc lập với tài liệu đang hiển thị. Chúng được dùng trong quy tắc @media của CSS để áp dụng kiểu có điều kiện cho một tài liệu, cũng như trong các ngữ cảnh và ngôn ngữ khác, chẳng hạn như HTML và JavaScript. Truy vấn nội dung đa phương tiện cấp 5 ra mắt tính năng nội dung đa phương tiện do người dùng ưu tiên, tức là một cách để các trang web phát hiện cách người dùng ưu tiên hiển thị nội dung.

Tính năng nội dung đa phương tiện prefers-color-scheme được dùng để phát hiện xem người dùng đã yêu cầu trang sử dụng giao diện màu sáng hay tối. Hàm này hoạt động với các giá trị sau:

  • light: Cho biết người dùng đã thông báo cho hệ thống rằng họ thích một trang có giao diện sáng (văn bản tối trên nền sáng).
  • dark: Cho biết người dùng đã thông báo cho hệ thống rằng họ thích một trang có giao diện tối (văn bản sáng trên nền tối).

Hỗ trợ chế độ tối

Tìm hiểu xem trình duyệt có hỗ trợ chế độ tối hay không

Vì chế độ tối được báo cáo thông qua một truy vấn nội dung đa phương tiện, nên bạn có thể dễ dàng kiểm tra xem trình duyệt hiện tại có hỗ trợ chế độ tối hay không bằng cách kiểm tra xem truy vấn nội dung đa phương tiện prefers-color-scheme có khớp hay không. Xin lưu ý cách tôi không cung cấp bất kỳ giá trị nào mà chỉ kiểm tra xem chỉ riêng cụm từ tìm kiếm nội dung đa phương tiện có khớp hay không.

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

Tại thời điểm viết bài, prefers-color-scheme được Chrome và Edge hỗ trợ trên cả máy tính và thiết bị di động (nếu có) kể từ phiên bản 76, Firefox phiên bản 67 và Safari kể từ phiên bản 12.1 trên macOS và phiên bản 13 trên iOS. Đối với tất cả những trình duyệt khác, bạn có thể xem phần Tôi có thể sử dụng bảng hỗ trợ không.

Tìm hiểu về các lựa chọn ưu tiên của người dùng tại thời điểm yêu cầu

Tiêu đề gợi ý của ứng dụng Sec-CH-Prefers-Color-Scheme cho phép các trang web lấy lựa chọn ưu tiên của người dùng trong bảng phối màu tại thời điểm yêu cầu, cho phép các máy chủ cùng dòng với CSS phù hợp và do đó tránh được việc chuyển sang chủ đề màu sắc không chính xác.

Chế độ tối trong thực tế

Cuối cùng hãy xem quá trình hỗ trợ chế độ tối trông như thế nào trong thực tế. Giống như với Highlander, với chế độ tối, chỉ có thể có một: tối hoặc sáng, nhưng không bao giờ có thể cả hai! Tại sao tôi đề cập đến điều này? Vì điều này sẽ có tác động đến chiến lược tải. Vui lòng không buộc người dùng tải CSS xuống trong đường dẫn hiển thị quan trọng dành cho chế độ mà họ hiện không sử dụng. Do đó, để tối ưu hoá tốc độ tải, tôi đã chia CSS của mình cho ứng dụng mẫu trình bày các đề xuất sau đây trong thực tế thành ba phần để trì hoãn CSS không quan trọng:

  • style.css chứa các quy tắc chung được sử dụng phổ biến trên trang web.
  • dark.css chỉ chứa các quy tắc cần thiết cho chế độ tối.
  • light.css chỉ chứa các quy tắc cần thiết cho chế độ sáng.

Chiến lược tải

Hai phần tử sau, light.cssdark.css, được tải có điều kiện bằng truy vấn <link media>. Ban đầu, không phải tất cả trình duyệt đều hỗ trợ prefers-color-scheme (có thể phát hiện bằng mẫu ở trên) mà tôi xử lý linh động bằng cách tải tệp light.css mặc định thông qua phần tử <link rel="stylesheet"> được chèn có điều kiện trong tập lệnh cùng dòng nhỏ (ánh sáng là lựa chọn tuỳ ý, tôi cũng có thể làm tối trải nghiệm dự phòng mặc định). Để tránh cài đặt ROM nội dung chưa định kiểu, tôi sẽ ẩn nội dung của trang cho đến khi light.css tải xong.

<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" />

Cấu trúc biểu định kiểu

Tôi tận dụng tối đa các biến CSS, điều này cho phép style.css chung của tôi trở thành chung chung và mọi hoạt động tuỳ chỉnh chế độ sáng hoặc tối đều diễn ra trong hai tệp khác dark.csslight.css. Bạn có thể xem phần trích dẫn các kiểu thực tế ở bên dưới, nhưng đủ để truyền tải ý tưởng tổng thể. Tôi khai báo 2 biến, -⁠-⁠color-⁠-⁠background-color để về cơ bản là tạo giao diện cơ sở tối trên sángsáng trên tối.

/* 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);
}

Trong style.css, tôi sử dụng các biến này trong quy tắc body { … }. Như được xác định trên :root CSS pseudo-class – một bộ chọn trong HTML đại diện cho phần tử <html> và giống với bộ chọn html, ngoại trừ việc chúng có tính đặc trưng cao hơn – chúng phân tầng xuống dưới, giúp tôi khai báo các biến CSS chung.

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

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

Trong mã mẫu ở trên, bạn có thể sẽ thấy một thuộc tính color-scheme có giá trị light dark được phân tách bằng dấu cách.

Thuộc tính này sẽ cho trình duyệt biết giao diện màu mà ứng dụng của tôi hỗ trợ và cho phép trình duyệt kích hoạt các biến thể đặc biệt của biểu định kiểu tác nhân người dùng. Ví dụ: để trình duyệt hiển thị các trường biểu mẫu với nền tối và văn bản sáng, điều chỉnh thanh cuộn hoặc bật màu đánh dấu có nhận biết giao diện. Thông tin chính xác về color-scheme được chỉ định trong Mô-đun điều chỉnh màu CSS cấp 1.

Mọi thứ còn lại chỉ là việc xác định các biến CSS cho những yếu tố quan trọng trên trang web của tôi. Việc sắp xếp kiểu theo ngữ nghĩa giúp ích rất nhiều khi sử dụng chế độ tối. Ví dụ: thay vì -⁠-⁠highlight-yellow, hãy cân nhắc gọi biến -⁠-⁠accent-color, vì "màu vàng" thực sự có thể không phải là màu vàng ở chế độ tối hoặc ngược lại. Dưới đây là ví dụ về một số biến khác mà tôi sử dụng trong ví dụ của mình.

/* 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);
}

Ví dụ đầy đủ

Trong phương thức nhúng Glitch sau đây, bạn có thể xem ví dụ đầy đủ về cách áp dụng các khái niệm ở trên vào thực tế. Hãy thử bật/tắt chế độ tối trong phần cài đặt của hệ điều hành cụ thể và xem trang phản ứng như thế nào.

Đang tải mức tác động

Khi xem ví dụ này, bạn có thể biết lý do tôi tải dark.csslight.css của mình thông qua các truy vấn nội dung đa phương tiện. Thử bật/tắt chế độ tối và tải lại trang: các biểu định kiểu cụ thể hiện không phù hợp vẫn được tải, nhưng với mức độ ưu tiên thấp nhất, để các biểu định kiểu không bao giờ cạnh tranh với các tài nguyên mà trang web cần ngay lúc này.

Sơ đồ tải mạng cho thấy cách CSS chế độ tối tải với mức độ ưu tiên thấp nhất ở chế độ sáng
Trang web ở chế độ sáng sẽ tải CSS chế độ tối có mức độ ưu tiên thấp nhất.
Sơ đồ tải mạng cho thấy cách CSS chế độ sáng tải CSS với mức độ ưu tiên thấp nhất ở chế độ tối
Trang web ở chế độ tối sẽ tải CSS chế độ sáng có mức độ ưu tiên thấp nhất.
Sơ đồ tải mạng cho thấy cách CSS chế độ tối tải với mức độ ưu tiên thấp nhất ở chế độ sáng mặc định
Trang web ở chế độ sáng mặc định trên trình duyệt không hỗ trợ prefers-color-scheme sẽ tải CSS chế độ tối có mức độ ưu tiên thấp nhất.

Phản ứng khi có thay đổi về chế độ tối

Giống như mọi thay đổi khác về truy vấn nội dung nghe nhìn, bạn có thể đăng ký các thay đổi về chế độ tối thông qua JavaScript. Chẳng hạn, bạn có thể sử dụng tính năng này để linh động thay đổi biểu tượng trang web của một trang hoặc thay đổi <meta name="theme-color"> xác định màu của thanh URL trong Chrome. Ví dụ đầy đủ ở trên minh hoạ điều này trong thực tế, để xem các thay đổi về màu giao diện và biểu tượng trang web, hãy mở bản minh hoạ trong một thẻ riêng.

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

Kể từ Chromium 93 và Safari 15, bạn có thể điều chỉnh màu dựa trên truy vấn nội dung nghe nhìn bằng thuộc tính media của phần tử màu giao diện meta. Mục đầu tiên phù hợp sẽ được chọn. Ví dụ: bạn có thể có một màu cho chế độ sáng và một màu khác cho chế độ tối. Tại thời điểm viết, bạn không thể xác định các thông số đó trong tệp kê khai. Hãy xem vấn đề w3c/manifest#975 trên GitHub.

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

Gỡ lỗi và thử nghiệm chế độ tối

Mô phỏng prefers-color-scheme trong Công cụ cho nhà phát triển

Việc chuyển đổi bảng phối màu của toàn bộ hệ điều hành có thể thực sự nhanh chóng gây khó chịu, vì vậy, Công cụ của Chrome cho nhà phát triển hiện cho phép bạn mô phỏng bảng phối màu ưu tiên của người dùng theo cách chỉ ảnh hưởng đến thẻ hiện đang hiển thị. Mở Trình đơn lệnh, bắt đầu nhập Rendering, chạy lệnh Show Rendering rồi thay đổi tuỳ chọn Mô phỏng tính năng đa phương tiện của CSS Preferreds-color-Schema.

Ảnh chụp màn hình lựa chọn &quot;Mô phỏng tính năng đa phương tiện của CSS Preferreds-color-lược đồ&quot; nằm trong thẻ Hiển thị của Công cụ của Chrome cho nhà phát triển

Đang chụp ảnh màn hình prefers-color-scheme bằng Puppeteer

Puppeteer là một thư viện Node.js cung cấp API cấp cao để kiểm soát Chrome hoặc Chromium thông qua DevTools Protocol. Với dark-mode-screenshot, chúng tôi cung cấp một tập lệnh Puppeteer cho phép bạn tạo ảnh chụp màn hình các trang ở cả chế độ tối và sáng. Bạn có thể chạy tập lệnh này dưới dạng một lần hoặc đặt tập lệnh này trong bộ thử nghiệm Tích hợp liên tục (CI).

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

Các phương pháp hay nhất về chế độ tối

Tránh màu trắng trơn

Một chi tiết nhỏ bạn có thể nhận thấy là tôi không sử dụng màu trắng tinh khiết. Thay vào đó, để tránh phát sáng và đổ máu đối với nội dung tối xung quanh, tôi chọn màu trắng tối hơn một chút. Ví dụ như rgb(250, 250, 250) hoạt động tốt.

Đổi màu lại và làm tối hình ảnh

Nếu so sánh 2 ảnh chụp màn hình dưới đây, bạn sẽ thấy rằng không chỉ giao diện chính đã thay đổi từ tối trên sáng sang sáng trên tối mà hình ảnh chính cũng hơi khác. Nghiên cứu về người dùng của tôi cho thấy phần lớn người được khảo sát thích những hình ảnh kém sống động và kém rực rỡ hơn một chút khi chế độ tối đang hoạt động. Tôi gọi đây là hiện tượng tái màu.

Hình ảnh chính bị làm tối một chút ở chế độ tối.
Hình ảnh chính bị tối một chút ở chế độ tối.
Hình ảnh chính thông thường ở chế độ sáng.
Hình ảnh chính thông thường ở chế độ sáng.

Việc tô màu lại có thể đạt được thông qua một bộ lọc CSS trên hình ảnh của tôi. Tôi dùng bộ chọn CSS khớp với tất cả hình ảnh không có .svg trong URL, ý tưởng là tôi có thể xử lý đồ hoạ vectơ (biểu tượng) cách xử lý đổi màu lại khác với hình ảnh của tôi (ảnh), hãy xem thêm thông tin về vấn đề này trong đoạn tiếp theo. Hãy lưu ý cách tôi sử dụng lại biến CSS để sau này có thể thay đổi linh hoạt bộ lọc của mình.

Vì chỉ cần tô màu lại ở chế độ tối, tức là khi dark.css đang hoạt động, sẽ không có quy tắc tương ứng nào trong light.css.

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

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

Tuỳ chỉnh cường độ tái tạo màu ở chế độ tối bằng JavaScript

Không phải ai cũng giống nhau và mỗi người có nhu cầu khác nhau về chế độ tối. Bằng cách làm theo phương pháp đổi màu lại như mô tả ở trên, tôi có thể dễ dàng đặt cường độ thang màu xám thành lựa chọn ưu tiên của người dùng mà tôi có thể thay đổi qua JavaScript và bằng cách đặt giá trị 0%, tôi cũng có thể tắt hoàn toàn tính năng tô màu lại. Xin lưu ý rằng document.documentElement cung cấp tệp tham chiếu đến thành phần gốc của tài liệu, tức là phần tử mà tôi có thể tham chiếu đến lớp giả CSS :root.

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

Đảo ngược đồ hoạ vectơ và biểu tượng

Đối với đồ hoạ vectơ (trong trường hợp của tôi được dùng làm biểu tượng mà tôi tham chiếu qua các phần tử <img>), tôi sẽ sử dụng một phương thức đổi màu khác. Mặc dù nghiên cứu đã chỉ ra rằng mọi người không thích chế độ đảo ngược ảnh, nhưng tính năng này hoạt động rất hiệu quả với hầu hết các biểu tượng. Xin nhắc lại, tôi sử dụng các biến CSS để xác định số tiền đảo ngược ở trạng thái thông thường và ở trạng thái :hover.

Các biểu tượng được đảo ngược ở chế độ tối.
Các biểu tượng được đảo ngược ở chế độ tối.
Biểu tượng thông thường ở chế độ sáng.
Biểu tượng thông thường ở chế độ sáng.

Hãy lưu ý lại, tôi chỉ đảo ngược các biểu tượng trong dark.css mà không phải trong light.css, và cách :hover có cường độ đảo ngược khác nhau trong hai trường hợp để làm cho biểu tượng có vẻ tối hơn hoặc sáng hơn một chút, tuỳ thuộc vào chế độ mà người dùng đã chọn.

/* 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);
}

Sử dụng currentColor cho các SVG cùng dòng

Đối với hình ảnh SVG nội tuyến, thay vì sử dụng bộ lọc đảo ngược, bạn có thể tận dụng từ khoá CSS currentColor biểu thị giá trị thuộc tính color của một phần tử. Điều này cho phép bạn sử dụng giá trị color trên các thuộc tính không nhận được giá trị đó theo mặc định. Điểm thuận tiện là nếu bạn dùng currentColor làm giá trị của các thuộc tính SVG fill hoặc stroke, thì hệ thống sẽ lấy giá trị từ giá trị kế thừa của thuộc tính màu. Hơn nữa, cách này cũng phù hợp với <svg><use href="…"></svg>, vì vậy, bạn có thể có các tài nguyên riêng và currentColor vẫn sẽ được áp dụng theo ngữ cảnh. Xin lưu ý rằng cách này chỉ áp dụng cho các SVG nội tuyến hoặc <use href="…">, chứ không phải các SVG được tham chiếu là src của hình ảnh hay theo cách nào đó qua CSS. Bạn có thể xem phương pháp này được áp dụng trong bản minh hoạ bên dưới.

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

Chuyển đổi mượt mà giữa các chế độ

Việc chuyển từ chế độ tối sang chế độ sáng hoặc ngược lại có thể được mượt mà nhờ thực tế là cả colorbackground-color đều là các thuộc tính CSS có thể tạo hình ảnh. Việc tạo ảnh động cũng dễ dàng như việc khai báo 2 transition cho 2 thuộc tính. Ví dụ bên dưới minh hoạ ý tưởng tổng thể và bạn có thể trải nghiệm ý tưởng trực tiếp trong bản minh hoạ.

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);
}

Hướng nghệ thuật bằng chế độ tối

Mặc dù vì lý do tải hiệu suất nói chung, bạn chỉ nên làm việc với prefers-color-scheme trong thuộc tính media của các phần tử <link> (thay vì cùng dòng trong biểu định kiểu), nhưng có những trường hợp bạn nên làm việc trực tiếp với prefers-color-scheme cùng dòng trong mã HTML. Chỉ đạo nghệ thuật chính là một trường hợp như vậy. Trên web, hướng nghệ thuật liên quan đến giao diện trực quan tổng thể của một trang và cách phương hướng đó giao tiếp trực quan, kích thích tâm trạng, tương phản các đặc điểm và thu hút đối tượng mục tiêu về mặt tâm lý.

Với chế độ tối, nhà thiết kế sẽ phải quyết định xem đâu là hình ảnh tốt nhất ở một chế độ cụ thể, và liệu việc tái màu hình ảnh có phải chưa đủ tốt hay không. Nếu được dùng với phần tử <picture>, thì <source> của hình ảnh hiển thị có thể phụ thuộc vào thuộc tính media. Trong ví dụ bên dưới, tôi hiển thị bán cầu Tây cho chế độ tối và bán cầu Đông cho chế độ sáng hoặc khi không có lựa chọn ưu tiên nào, đặt mặc định là bán cầu phương Đông trong tất cả các trường hợp khác. Tất nhiên, thông tin này chỉ nhằm mục đích minh hoạ. Bật chế độ tối trên thiết bị để xem sự khác biệt.

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

Chế độ tối, nhưng thêm một nút chọn không sử dụng

Như đã đề cập trong phần lý do nên sử dụng chế độ tối ở trên, chế độ tối là một lựa chọn mang tính thẩm mỹ của hầu hết người dùng. Do đó, một số người dùng có thể thực sự muốn đặt giao diện người dùng hệ điều hành ở chế độ tối, nhưng vẫn muốn xem các trang web như cách họ đã quen xem. Một cách hay là ban đầu nên tuân thủ tín hiệu mà trình duyệt gửi qua prefers-color-scheme, nhưng sau đó tuỳ ý cho phép người dùng ghi đè chế độ cài đặt cấp hệ thống của họ.

Phần tử tuỳ chỉnh <dark-mode-toggle>

Tất nhiên, bạn có thể tự tạo mã cho việc này, nhưng bạn cũng có thể chỉ cần sử dụng phần tử tuỳ chỉnh có sẵn (thành phần web) mà tôi đã tạo đúng cho mục đích này. Giao diện này được gọi là <dark-mode-toggle> và thêm nút bật/tắt (chế độ tối: bật/tắt) hoặc trình chuyển đổi giao diện (giao diện: sáng/tối) vào trang mà bạn có thể tuỳ chỉnh hoàn toàn. Bản minh hoạ dưới đây cho thấy phần tử này đang hoạt động (trời ơi, tôi cũng đã 🤫 đã lặng lẽ nhắc đến phần tử này trong tất cả các ví dụ khác ở trên).

<dark-mode-toggle
  legend="Theme Switcher"
  appearance="switch"
  dark="Dark"
  light="Light"
  remember="Remember this"
></dark-mode-toggle>
bật-tắt chế độ tối ở chế độ sáng.
<dark-mode-toggle> ở chế độ sáng.
bật-tắt chế độ tối ở chế độ sáng.
<dark-mode-toggle> ở chế độ tối.

Hãy thử nhấp hoặc nhấn vào các nút điều khiển chế độ tối ở góc trên bên phải trong bản minh hoạ bên dưới. Nếu bạn chọn hộp đánh dấu trong thành phần điều khiển thứ ba và thứ tư, hãy xem cách hệ thống ghi nhớ lựa chọn chế độ của bạn ngay cả khi bạn tải lại trang. Điều này cho phép khách truy cập duy trì hệ điều hành của họ ở chế độ tối, nhưng tận hưởng trang web của bạn ở chế độ sáng hoặc ngược lại.

Kết luận

Việc sử dụng và hỗ trợ chế độ tối rất thú vị và giúp mở ra những hướng thiết kế mới. Đối với một số khách truy cập của bạn, sự khác biệt giữa việc không thể xử lý trang web và việc khiến người dùng hài lòng có thể là Có một số sai lầm và bạn chắc chắn phải thử nghiệm cẩn thận. Tuy nhiên, chế độ tối chắc chắn là cơ hội tuyệt vời để bạn thể hiện rằng bạn quan tâm đến tất cả người dùng. Các phương pháp hay nhất được đề cập trong bài đăng này và các trình trợ giúp như phần tử tuỳ chỉnh <dark-mode-toggle> sẽ giúp bạn tự tin vào khả năng tạo ra trải nghiệm tuyệt vời ở chế độ tối. Hãy cho tôi biết trên Twitter nội dung bạn tạo và liệu bài đăng này có hữu ích hay không hoặc cũng có đề xuất để cải thiện bài đăng. Cảm ơn bạn đã đọc! 🌒

Tài nguyên cho truy vấn nội dung nghe nhìn prefers-color-scheme:

Tài nguyên dành cho thẻ meta color-scheme và thuộc tính CSS:

Đường liên kết chung về chế độ tối:

Các bài viết nghiên cứu cơ bản cho bài đăng này:

Xác nhận

Tính năng đa phương tiện prefers-color-scheme, thuộc tính CSS color-scheme và thẻ meta liên quan là công việc triển khai của 👏 Rune Lillesveen. Rune cũng là đồng biên tập nội dung kỹ thuật Mô-đun điều chỉnh màu CSS cấp 1. Xin 🙏 cảm ơn Lukasz Zbylut, Rowan Merewood, Chirag Desai, và Rob Dodson đã đánh giá kỹ lưỡng bài viết này. Chiến lược tải là sáng kiến của Jake Archibald. Emilio Cobos Álvarez đã chỉ cho tôi phương pháp phát hiện prefers-color-scheme chính xác. Mẹo có SVG và currentColor được tham chiếu đến từ Timothy Hatcher. Cuối cùng, tôi rất cảm ơn những người tham gia ẩn danh trong các nghiên cứu người dùng khác nhau đã giúp định hình các đề xuất trong bài viết này. Hình ảnh chính của Nathan Anderson.