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

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

Giới thiệu

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

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

Chúng tôi đã phát triển toàn diện nhờ chế độ tối. Trong buổi bình minh của điện toán cá nhân, chế độ tối không phải là lựa chọn đầu tiên, nhưng trên thực tế: Màn hình máy tính CRT đơn sắc hoạt động bằng cách kích hoạt các tia electron trên màn hình huỳnh quang và phốt pho được sử dụng trong CRT ban đầu có màu xanh lục. Do 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 có màu đen, nên những mô hình này thường được gọi là màn hình xanh lục.

Xử lý văn bản ở chế độ tối trắng
Màu trắng đen (Nguồn)

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

Trang web màu trắng đen trong trình duyệt WorldwideWeb
Trình duyệt WorldwideWeb (Nguồn)

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

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

Thời kỳ sử dụng CRT đã qua lâu rồi. Việc sáng tạo và xem nội dung đã chuyển sang thiết bị di động sử dụng 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 với kích thước nhỏ hơn và dễ di chuyển hơn dẫn đến thói quen sử dụng mới. 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 xảy ra sau giờ làm việc trong môi trường tối. Vào buổi tối, mọi người thậm chí còn sử dụng thiết bị trên giường. Càng nhiều người sử dụng thiết bị trong bóng tối, thì ý tưởng quay lại gốc rễ của chế độ sáng trên tối càng trở nên phổ biến.

Tại sao nên sử dụng chế độ tối

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

Khi mọi người được hỏi lý do họ thích hoặc muốn chế độ tối, phản hồi phổ biến nhất là "nhìn dễ nhìn hơn" tiếp theo là "kiểu trang nhã và đẹp mắt." Apple trong Tài liệu dành cho nhà phát triển về Chế độ tối viết rõ ràng: "Lựa chọn bật giao diện sáng hay tối là một tính năng mang tính thẩm mỹ đối với 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 Mac OS System 7 với
System 7 CloseView (Nguồn)

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

Cũng có những người thực sự cần sử dụng chế độ tối như một công cụ hỗ trợ tiếp cận khác, ví dụ: 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 Hệ thống 7 có nút bật/tắt đối với Trắng trên nền trắngTrắng trên nền đen. Mặc dù màu sắc hỗ trợ Hệ thống 7, nhưng giao diện người dùng mặc định vẫn là màu đen trắng.

Những cách triển khai dựa trên đảo ngược này đã cho thấy điểm yếu của chúng khi màu được đưa vào. Nghiên cứu về người dùng của Szpiro và đồng sự về cách người có thị lực kém sử dụng thiết bị điện toán cho thấy tất cả 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 dùng văn bản sáng 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 là Đảo ngược thông minh, đảo ngược màu sắc trên màn hình, ngoại trừ hình ảnh, nội dung đa phương tiện, và một số ứng dụng 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ị lực máy tính, còn được gọi là Căng mắt số, được xác định"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ử)." Điều này đã được đề xuất việc thanh thiếu niên sử dụng thiết bị điện tử, đặc biệt là vào ban đêm, sẽ làm tăng nguy cơ thời gian ngủ ngắn hơn, thời gian chờ bắt đầu ngủ dài hơn và tình trạng thiếu ngủ gia tăng. Ngoài ra, việc phơi nhiễm với ánh sáng xanh là báo cáo tham gia vào việc điều chỉnh nhịp sinh học và chu kỳ ngủ, và môi trường ánh sáng không đều 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ế những tác động tiêu cực này, hãy giảm ánh sáng xanh 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ư iOS Chế độ Night Shift hoặc của Android Ánh sáng đêm có thể giúp bạn cũng như tránh ánh sáng mạnh hoặc ánh sáng không đều nói chung thông qua giao diện tối hoặc chế độ tối.

Chế độ tối tiết kiệm pin trên màn hình AMOLED

Cuối cùng, chế độ tối được biết là giúp tiết kiệm rất nhiều năng lượng Màn hình AMOLED. 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 đến 60%. Video dưới đây có thêm thông tin chi tiết 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.

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

Giờ thì tôi đã giải thích được lý do tại sao chế độ tối lại là một vấn đề quan trọng đối với nhiều người dùng, hãy cùng xem bạn có thể hỗ trợ bằng cách nào.

Cài đặt chế độ tối trên Android Q
Chế độ cài đặt giao diện tối cho Android Q

Các hệ điều hành hỗ trợ chế độ tối hoặc giao diện tối thường có lựa chọn kích hoạt ở đâu đó trong phần cài đặt. Trên macOS X, trình đơn này nằm trong phần General (Chung) của tuỳ chọn hệ thống và có tên là Appearance (Giao diện) (ảnh chụp màn hình), và trên Windows 10, ứng dụng này nằm trong phần Colors (Màu) và có tên là Choose your color (Chọn màu của bạn) (ảnh chụp màn hình). Đối với Android Q, bạn có thể tìm thấy chế độ này trong mục Display (Hiển thị) dưới dạng nút 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 giao diện Giao diện trong mục Hiển thị và Độ sáng của cài đặt (ảnh chụp màn hình).

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

Một chút lý thuyết cuối cùng trước khi tôi bắt đầu. Truy vấn về nội dung nghe nhìn cho phép tác giả kiểm tra 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 được hiển thị. Các mẫu này được dùng trong quy tắc @media CSS để áp dụng các kiểu có điều kiện cho một tài liệu, cũng như trong nhiều 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 một tính năng được gọi là tính năng truyền thông theo sở thích của người dùng, tức là một cách để các trang web phát hiện ra cách thức ưu tiên của người dùng để hiển thị nội dung.

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

  • light: Cho biết rằng 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 rằng người dùng đã thông báo cho hệ thống rằng họ muốn dùng 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 nghe nhìn, bạn có thể dễ dàng kiểm tra xem trình duyệt hiện tại có có hỗ trợ chế độ tối bằng cách kiểm tra xem truy vấn đa phương tiện prefers-color-scheme có khớp hoàn toàn hay không. Lưu ý rằng tôi không đưa vào bất kỳ giá trị nào, mà chỉ kiểm tra xem liệu truy vấn phương tiện có phù hợ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 hỗ trợ trên cả máy tính và thiết bị di động (nếu có) của Chrome và Edge 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à kể từ phiên bản 13 trên iOS. Đối với tất cả 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ề 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 ý ứng dụng Sec-CH-Prefers-Color-Scheme cho phép các trang web lấy lựa chọn ưu tiên về bảng phối màu của người dùng tại thời điểm yêu cầu, cho phép máy chủ đặt nội tuyến CSS phù hợp và do đó tránh được hiện tượng nhấp nháy chủ đề màu sắc không chính xác.

Chế độ tối đang được áp dụng

Hãy cùng xem cách hỗ trợ chế độ tối trong thực tế. Giống như với Highlander, với chế độ tối, chỉ có một: tối hoặc sáng, nhưng không bao giờ có cả hai! Tại sao tôi lại đề cập đến điều này? Bởi vì thực tế này sẽ ảnh hưở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 đã phân tách CSS của mình cho ứng dụng mẫu hiển thị các đề xuất sau trong thực tế thành ba phần nhằm trì hoãn CSS không quan trọng:

  • style.css chứa các quy tắc chung được sử dụng rộng rãi 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 chế độ 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 trình duyệt nào cũng hỗ trợ prefers-color-scheme (có thể phát hiện bằng cách sử dụng mẫu ở trên), mà tôi xử lý động bằng cách tải tệp light.css mặc định qua phần tử <link rel="stylesheet"> được chèn có điều kiện trong một tập lệnh cùng dòng cực nhỏ (sáng là một lựa chọn tuỳ ý, tôi cũng có thể đặt màu tối làm trải nghiệm dự phòng mặc định). Để tránh hiện nội dung không theo kiểu, Tôi ẩ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 khai thác tối đa biến CSS, điều này cho phép style.css chung của tôi trở thành còn mọi chế độ tuỳ chỉnh sáng hoặc tối đều diễn ra trong hai tệp khác là dark.csslight.css. Dưới đây bạn có thể xem phần trích dẫn các kiểu thực tế, nhưng đủ để truyền tải ý tưởng chung. Tôi khai báo hai biến là -⁠-⁠color-⁠-⁠background-color về cơ bản để tạo giao diện cơ sở bật sángsáng-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ẽ sử dụng các biến này trong quy tắc body { … }. Như được xác định trên Lớp giả lập CSS :root – 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 cụ thể là bộ chọn này chúng tăng lên, giúp tôi khai báo các biến CSS toàn cục.

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

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

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

Thông tin này cho trình duyệt biết ứng dụng của tôi hỗ trợ chủ đề màu nào và cho phép tác nhân người dùng 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, điều này rất hữu ích, chẳng hạn như giúp trình duyệt hiển thị các trường biểu mẫu có nền tối và văn bản sáng, hãy điều chỉnh các thanh cuộn, hoặc để bật màu đánh dấu nhận biết chủ đề. Thông tin chi tiết chính xác về color-scheme được nêu rõ trong Mô-đun điều chỉnh màu CSS cấp 1.

Mọi thứ khác chỉ là vấn đề xác định biến CSS cho những điều quan trọng trên trang web của tôi. Việc sắp xếp các kiểu theo ngữ nghĩa sẽ giúp ích rất nhiều khi làm việc với chế độ tối. Ví dụ: thay vì -⁠-⁠highlight-yellow, hãy cân nhắc gọi biến -⁠-⁠accent-color, là "màu vàng" thực ra không phải là màu vàng khi ở 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 nội dung nhúng nhiễu sau, bạn có thể xem ví dụ đầy đủ để á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 hệ điều hành cụ thể của bạn và xem cách trang phản ứng.

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

Khi thử nghiệm ví dụ này, bạn có thể thấy tại sao tôi tải dark.csslight.css thông qua các truy vấn phương tiện. Hãy thử bật/tắt chế độ tối rồi 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, để họ không bao giờ cạnh tranh với các tài nguyên mà trang web cần ngay bây giờ.

Sơ đồ tải mạng cho thấy cách CSS ở chế độ tối được 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 với mức độ ưu tiên thấp nhất.
Sơ đồ tải mạng cho thấy cách CSS ở chế độ sáng được tải 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 với mức độ ưu tiên thấp nhất.
Sơ đồ tải mạng cho thấy cách CSS ở chế độ tối được tải ở chế độ sáng mặc định với mức độ ưu tiên thấp nhất
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 thay đổi chế độ tối

Giống như mọi thay đổi khác về truy vấn nội dung nghe nhìn, người dùng có thể đăng ký các thay đổi đối với chế độ tối thông qua JavaScript. Ví dụ: bạn có thể sử dụng tuỳ chọn này để thay đổi linh động biểu tượng yêu thích hoặc thay đổi <meta name="theme-color"> giúp xác định màu của thanh URL trong Chrome. Ví dụ đầy đủ ở trên cho thấy điều này trong thực tế, để xem màu của giao diện và biểu tượng trang web thay đổi, 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 sắc dựa theo truy vấn đa phương tiện có thuộc tính media của phần tử màu giao diện meta. Chiến lược phát hành đĩa đơn 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 chế độ khác cho chế độ tối. Tại thời điểm viết bài này, bạn không thể hãy xác định các mã đó trong tệp kê khai. Xem 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ể 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, sau đó thay đổi tuỳ chọn Mô phỏng tính năng đa phương tiện của CSS trong ưu tiên-màu-sắc-lược.

Ảnh chụp màn hình thẻ &quot;Mô phỏng tính năng đa phương tiện của CSS&quot; nằm trong thẻ Kết xuất của Công cụ cho nhà phát triển của Chrome

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 qua Giao thức DevTools. Với dark-mode-screenshot, chúng tôi cung cấp tập lệnh Puppeteer cho phép bạn tạo ảnh chụp màn hình cho các trang ở cả chế độ tối và sáng. Bạn có thể chạy tập lệnh này một lần hoặc đưa tập lệnh này vào Bộ kiểm tra 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 tinh khiết

Một chi tiết nhỏ mà 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 đó, để ngăn hiện tượng sáng và chảy máu so với nội dung tối xung quanh, Tôi chọn màu trắng hơi tối hơn. Ví dụ như rgb(250, 250, 250) hoạt động tốt.

Đổi màu và làm tối ảnh chụp

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

Hình ảnh chính bị làm tối nhẹ ở chế độ tối.
Hình ảnh chính bị làm tối nhẹ ở 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.

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

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

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

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

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

Không phải mọi người đều như 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 tô màu lại được mô tả ở trên, Tôi có thể dễ dàng đặt cường độ thang màu xám làm lựa chọn ưu tiên của người dùng 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. Lưu ý rằng document.documentElement cung cấp một tham chiếu đến phần tử gốc của tài liệu, tức là chính yếu tố tôi có thể tham chiếu với :root Lớp giả CSS.

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

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

Đố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 thông qua các phần tử <img> – tôi dùng phương pháp tô màu lại khác. Mặc dù nghiên cứu đã cho thấy mà mọi người không thích đảo ngược cho ảnh, tính năng này hoạt động rất tốt với hầu hết các biểu tượng. Một lần nữa, tôi sử dụng các biến CSS để xác định số lượng đảo ngược ở trạng thái thông thường và ở trạng thái :hover.

Các biểu tượng bị đảo ngược ở chế độ tối.
Các biểu tượng bị đả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.

Xin lưu ý một lần nữa, tôi chỉ đảo ngược các biểu tượng trong dark.css chứ không phải trong light.css, và cách :hover sẽ có cường độ đảo ngược khác nhau trong hai trường hợp để làm biểu tượng xuất hiện tối hơn một chút 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);
}

Dùng currentColor cho 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 currentColor Từ khoá CSS đại diện cho 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 tài sản không nhận được theo mặc định. Một cách thuận tiện là nếu currentColor được dùng làm giá trị của SVG Thuộc tính fill hoặc stroke, thay vào đó, nó sẽ lấy giá trị từ giá trị kế thừa của thuộc tính màu sắc. Tốt hơn nữa: điều này cũng hiệu quả cho <svg><use href="…"></svg>! để bạn có thể có các tài nguyên riêng biệt và currentColor vẫn sẽ được áp dụng theo ngữ cảnh. Xin lưu ý rằng tính năng này chỉ hoạt động với SVG nội tuyến hoặc <use href="…">, nhưng không phải là SVG được tham chiếu dưới dạng src của hình ảnh hoặc bằng cách nào đó thông qua CSS. Bạn có thể xem điều 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 thực hiện mượt mà nhờ trên thực tế cả colorbackground-color đều là thuộc tính CSS có thể tạo. 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ụ dưới đây minh hoạ ý tưởng chung, bạn có thể trải nghiệm ý tưởng này 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 với chế độ tối

Mặc dù vì lý do tải hiệu suất nói chung, tôi khuyên 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), có những trường hợp mà bạn có thể thực sự muốn làm việc với prefers-color-scheme ngay trong nội dung mã HTML. Hướng nghệ thuật là một tình huống như vậy. Trên web, định hướng nghệ thuật liên quan đến giao diện hình ảnh tổng thể của trang cũng như cách trang truyền tải thông tin trực quan, kích thích tâm trạng, tương phản các đặc điểm và thu hút khán giả mục tiêu về mặt tâm lý.

Với chế độ tối, nhà thiết kế có thể quyết định hình ảnh nào đẹp nhất ở một chế độ cụ thể và liệu việc tô màu lại hình ảnhkhông đủ hiệu quả hay không. Nếu sử dụng cùng với phần tử <picture>, <source> của hình ảnh xuất hiện có thể trở thành 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, giá trị mặc định sẽ là bán cầu Đông trong tất cả các trường hợp khác. Tất nhiên, bài viết này chỉ nhằm mục đích minh hoạ. Bật/tắt chế độ tối trên thiết bị để thấy 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 chế độ chọn không sử dụng

Như đã đề cập trong phần lý do sử dụng chế độ tối ở trên, chế độ tối là lựa chọn làm đẹp cho hầu hết người dùng. Do đó, một số người dùng có thể thực sự muốn có giao diện người dùng của hệ điều hành ở chế độ tối, nhưng vẫn thích xem trang web theo cách họ quen xem. Tốt nhất là bạn nên tuân thủ tín hiệu mà trình duyệt gửi ngay từ đầu prefers-color-scheme, nhưng cho phép người dùng ghi đè chế độ cài đặt ở cấp hệ thống (không bắt buộc).

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

Tất nhiên, bạn có thể tự tạo mã cho quy trình này, nhưng bạn cũng có thể chỉ cần sử dụng một phần tử tuỳ chỉnh tạo sẵn (thành phần web) mà tôi đã tạo cho mục đích này. Đó là <dark-mode-toggle> và nút này sẽ thêm một nút chuyển (chế độ tối: bật/tắt) hoặc trình chuyển đổi chủ đề (giao diện: sáng/tối) cho trang mà bạn có thể tuỳ chỉnh hoàn toàn. Bản minh hoạ dưới đây cho thấy cách hoạt động của phần tử này (và tôi cũng đã 🤫 âm thầm ẩn nó vào tất cả khác ví dụ ở 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 kiểm trong điều khiển thứ ba và thứ tư, hãy xem cách lựa chọn chế độ của bạn sẽ được ghi nhớ ngay cả khi bạn tải lại trang. Nhờ đó, khách truy cập có thể 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 tương tác và hỗ trợ chế độ tối là một trải nghiệm thú vị và mở ra những con đường thiết kế mới. Đối với một số khách truy cập của bạn, đó có thể là sự khác biệt giữa việc không thể xử lý trang web của bạn và trở thành một người dùng hài lòng. Có một số sai lầm và chắc chắn bạn phải kiểm tra kỹ lưỡng nhưng chế độ tối chắc chắn là một 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 khi sử dụng chế độ tối. Hãy cho tôi biết trên Twitter về 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ó thể đề xuất cách cải thiện. Cảm ơn bạn đã đọc! 🌒

Tài nguyên dành cho truy vấn phương tiện prefers-color-scheme:

Các tài nguyên 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ười đồng chỉnh sửa thông số CSS Color Adjustment Module Level 1 (Mô-đun điều chỉnh màu CSS). Tôi muốn 🙏 cảm ơn Lukasz Zbylut! Rowan Merewood, Chirag Desai, và Rob Dodson để xem các bài đánh giá kỹ lưỡng về bài viết này. Chiến lược tải là sản phẩm tinh thầ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. Tiền boa có các SVG và currentColor được tham chiếu đến từ Timothy Hatcher. Cuối cùng, tôi biết ơn nhiều người tham gia ẩn danh trong nhiều nghiên cứu người dùng đã 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.