Cải thiện kiểu mặc định của chế độ tối bằng thuộc tính CSS phối màu và thẻ meta tương ứng

Thuộc tính CSS color-scheme và thẻ meta tương ứng cho phép nhà phát triển chọn áp dụng các chế độ mặc định theo giao diện cụ thể của biểu định kiểu tác nhân người dùng cho các trang của mình.

Thông tin khái quát

Tính năng đa phương tiện tùy chọn người dùng prefers-color-scheme

Tính năng nội dung đa phương tiện theo lựa chọn ưu tiên của người dùng prefers-color-scheme cho phép nhà phát triển kiểm soát hoàn toàn giao diện của trang. Nếu bạn chưa hiểu rõ về tính năng này, vui lòng đọc bài viết của tôi prefers-color-scheme: Xin chào bóng tối, người bạn cũ của tôi. Tôi đã ghi lại mọi thứ tôi biết về cách tạo trải nghiệm tuyệt vời ở chế độ tối.

Một mảnh ghép chỉ được đề cập ngắn gọn trong bài viết là thuộc tính CSS color-scheme và thẻ meta tương ứng cùng tên. Cả hai đều giúp bạn làm nhà phát triển dễ dàng hơn bằng cách cho phép trang của mình sử dụng các giá trị mặc định theo chủ đề cụ thể của biểu định kiểu tác nhân người dùng, chẳng hạn như thành phần điều khiển biểu mẫu, thanh cuộn và màu hệ thống CSS. Đồng thời, tính năng này không cho các trình duyệt tự áp dụng bất kỳ quy tắc chuyển đổi nào.

Hỗ trợ trình duyệt

prefers-color-scheme

Hỗ trợ trình duyệt

  • 76
  • 79
  • 67
  • 12,1

Nguồn

color-scheme

Hỗ trợ trình duyệt

  • 81
  • 81
  • 96
  • 13

Nguồn

Biểu định kiểu tác nhân người dùng

Trước khi tiếp tục, tôi sẽ mô tả ngắn gọn về biểu định kiểu tác nhân người dùng. Trong hầu hết trường hợp, bạn có thể hiểu từ tác nhân người dùng (UA) như một cách nói khác dễ hiểu về trình duyệt. Biểu định kiểu UA xác định giao diện mặc định của trang. Đúng như tên gọi, biểu định kiểu UA phụ thuộc vào UA được đề cập. Bạn có thể xem biểu định kiểu UA của Chrome (và Chromium) và so sánh với biểu định kiểu UA của Firefox hoặc Safari (và WebKit). Thông thường, các biểu định kiểu UA đồng ý với phần lớn nội dung. Ví dụ: tất cả đều tạo đường liên kết màu xanh dương, màu văn bản chung là đen và màu nền trắng, nhưng cũng có những điểm khác biệt quan trọng (và đôi khi gây khó chịu), chẳng hạn như cách chúng tạo kiểu cho các thành phần điều khiển biểu mẫu.

Xem kỹ hơn biểu định kiểu UA của WebKit và tác dụng của biểu định kiểu UA đối với chế độ tối. (Thực hiện tìm kiếm văn bản đầy đủ cho "tối" trong biểu định kiểu.) Mặc định do biểu định kiểu cung cấp sẽ thay đổi tuỳ theo việc chế độ tối đang bật hay tắt. Để minh hoạ điều này, dưới đây là một quy tắc CSS như vậy bằng cách sử dụng lớp giả :matches và biến WebKit-internal như -apple-system-control-background, cũng như lệnh WebKit-internal tiền xử lý #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 */
}

Bạn sẽ thấy một số giá trị không chuẩn cho các thuộc tính colorbackground-color ở trên. Cả text-apple-system-control-background đều không phải là màu CSS hợp lệ. Đây là màu ngữ nghĩa nội bộ WebKit.

Hoá ra CSS đã chuẩn hoá màu hệ thống ngữ nghĩa. Các màu này được chỉ định trong Mô-đun màu CSS cấp 4. Ví dụ: Canvas (đừng nhầm lẫn với thẻ <canvas>) dành cho nền của nội dung hoặc tài liệu ứng dụng, trong khi CanvasText dành cho văn bản trong nội dung hoặc tài liệu ứng dụng. Hai yếu tố này đi kèm với nhau và không nên được sử dụng riêng biệt.

Biểu định kiểu UA có thể sử dụng màu độc quyền của riêng chúng hoặc màu hệ thống ngữ nghĩa được chuẩn hoá để xác định cách hiển thị các phần tử HTML theo mặc định. Nếu hệ điều hành được đặt ở chế độ tối hoặc sử dụng giao diện tối, thì CanvasText (hoặc text) sẽ được đặt thành màu trắng theo điều kiện, còn Canvas (hoặc -apple-system-control-background) sẽ được đặt thành màu đen. Sau đó, biểu định kiểu UA chỉ gán CSS sau đây một lần và bao gồm cả chế độ sáng và tối.

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

Thuộc tính CSS color-scheme

Thông số kỹ thuật Mô-đun điều chỉnh màu CSS cấp 1 giới thiệu một mô hình và các chế độ điều khiển đối với tính năng điều chỉnh màu tự động của tác nhân người dùng nhằm xử lý các lựa chọn ưu tiên của người dùng, chẳng hạn như chế độ tối, điều chỉnh độ tương phản hoặc bảng phối màu cụ thể mong muốn.

Thuộc tính color-scheme được xác định trong đó cho phép một phần tử cho biết bảng phối màu phù hợp khi kết xuất. Các giá trị này được thương lượng với lựa chọn ưu tiên của người dùng, dẫn đến bảng phối màu được chọn sẽ ảnh hưởng đến các nội dung trên giao diện người dùng (UI) chẳng hạn như màu mặc định của các thành phần điều khiển biểu mẫu và thanh cuộn, cũng như các giá trị được sử dụng của màu hệ thống CSS. Các giá trị sau hiện được hỗ trợ:

  • normal Cho biết phần tử không biết bảng phối màu và vì vậy phần tử phải được kết xuất bằng bảng phối màu mặc định của trình duyệt.

  • [ light | dark ]+ Cho biết phần tử biết và có thể xử lý các bảng phối màu được liệt kê, đồng thời thể hiện lựa chọn ưu tiên theo thứ tự giữa các bảng phối màu đó.

Trong danh sách này, light đại diện cho bảng phối màu sáng, với màu nền sáng và màu nền trước tối, trong khi dark đại diện cho điều ngược lại, với màu nền tối và màu nền trước sáng.

Đối với tất cả các phần tử, việc hiển thị bằng bảng phối màu phải khiến màu sắc được sử dụng trong tất cả giao diện người dùng do trình duyệt cung cấp cho phần tử đó khớp với ý định của bảng phối màu. Ví dụ: thanh cuộn, dấu gạch dưới kiểm tra lỗi chính tả, thành phần điều khiển biểu mẫu, v.v.

Trên phần tử :root, việc kết xuất bằng bảng phối màu còn phải ảnh hưởng đến màu bề mặt của canvas (tức là màu nền chung), giá trị ban đầu của thuộc tính color và các giá trị được sử dụng của màu hệ thống, đồng thời cũng phải ảnh hưởng đến thanh cuộn của khung nhìn.

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

Thẻ meta color-scheme

Để tuân thủ thuộc tính CSS color-scheme, bạn phải tải CSS xuống trước (nếu CSS này được tham chiếu thông qua <link rel="stylesheet">) và phải được phân tích cú pháp. Để hỗ trợ các tác nhân người dùng kết xuất nền của trang bằng bảng phối màu mong muốn ngay lập tức, bạn cũng có thể cung cấp giá trị color-scheme trong phần tử <meta name="color-scheme">.

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

Kết hợp color-schemeprefers-color-scheme

Vì cả thẻ meta và thuộc tính CSS (nếu áp dụng cho phần tử :root) cuối cùng đều dẫn đến cùng một hành vi, nên bạn nên chỉ định bảng phối màu thông qua thẻ meta để trình duyệt có thể áp dụng lược đồ ưu tiên nhanh hơn.

Mặc dù đối với các trang cơ sở tuyệt đối, bạn không cần thêm quy tắc CSS nào, nhưng trong trường hợp chung, bạn phải luôn kết hợp color-scheme với prefers-color-scheme. Ví dụ: màu WebKit CSS độc quyền -webkit-link, được WebKit và Chrome sử dụng cho màu xanh dương liên kết cổ điển rgb(0,0,238), có tỷ lệ tương phản không đủ là 2,23:1 trên nền đen và không được cả WCAG AA cũng như các yêu cầu của WCAG AAA.

Tôi đã mở các lỗi cho Chrome, WebKitFirefox cũng như vấn đề meta trong HTML chuẩn để khắc phục vấn đề này.

Tương tác với prefers-color-scheme

Lúc đầu, việc tương tác của thuộc tính CSS color-scheme và thẻ meta tương ứng với tính năng nội dung đa phương tiện lựa chọn ưu tiên của người dùng prefers-color-scheme có thể khiến bạn nhầm lẫn. Thực tế, họ chơi với nhau rất ăn ý. Điều quan trọng nhất cần hiểu là color-scheme xác định độc quyền giao diện mặc định, trong khi prefers-color-scheme xác định giao diện có cách điệu. Để làm cho điều này rõ ràng hơn, hãy giả định trang sau:

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

Mã CSS cùng dòng trên trang đặt background-color của phần tử <fieldset> thành gainsboro trong trường hợp chung và thành darkslategray nếu người dùng ưu tiên bảng phối màu dark theo tính năng đa phương tiện lựa chọn ưu tiên của người dùng prefers-color-scheme.

Thông qua phần tử <meta name="color-scheme" content="dark light">, trang cho trình duyệt biết rằng trang có hỗ trợ giao diện tối và sáng, với lựa chọn ưu tiên về giao diện tối.

Tuỳ thuộc vào việc hệ điều hành được đặt ở chế độ tối hay sáng, toàn bộ trang sẽ hiển thị ở chế độ sáng khi tối hoặc ngược lại, dựa trên biểu định kiểu tác nhân người dùng. Nhà phát triển không cung cấp thêm CSS nào liên quan đến việc thay đổi văn bản của đoạn văn bản hoặc màu nền của trang.

Hãy lưu ý cách background-color của phần tử <fieldset> thay đổi dựa trên việc có bật chế độ tối hay không, tuân theo các quy tắc trong biểu định kiểu cùng dòng do nhà phát triển cung cấp trên trang. Đó là gainsboro hoặc darkslategray.

Một trang ở chế độ sáng.
Chế độ sáng: Kiểu do nhà phát triển và tác nhân người dùng chỉ định. Văn bản có màu đen và nền màu trắng theo biểu định kiểu tác nhân người dùng. background-color của phần tử <fieldset>gainsboro theo biểu định kiểu dành cho nhà phát triển cùng dòng.
Một trang ở chế độ tối.
Chế độ tối: Kiểu do nhà phát triển và tác nhân người dùng chỉ định. Văn bản có màu trắng và nền màu đen theo biểu định kiểu tác nhân người dùng. background-color của phần tử <fieldset>darkslategray theo biểu định kiểu dành cho nhà phát triển cùng dòng.

Giao diện của phần tử <button> được kiểm soát bởi biểu định kiểu tác nhân người dùng. color của lớp này được đặt thành màu hệ thống ButtonText, còn background-color và 4 border-color của lớp này được đặt thành màu hệ thống ButtonFace.

Một trang chế độ sáng sử dụng thuộc tính ButtonFace.
Chế độ sáng: background-color và nhiều border-color khác nhau được đặt thành màu hệ thống ButtonFace.

Bây giờ, hãy lưu ý đến cách border-color của phần tử <button> thay đổi. Giá trị được tính cho border-top-colorborder-bottom-color chuyển từ rgba(0, 0, 0, 0.847) (màu đen) sang rgba(255, 255, 255, 0.847) (màu trắng), do tác nhân người dùng cập nhật ButtonFace linh hoạt dựa trên bảng phối màu. Điều này cũng áp dụng cho color của phần tử <button> được đặt thành màu hệ thống tương ứng ButtonText.

Cho thấy các giá trị màu đã tính toán khớp với ButtonFace.
Chế độ sáng: Các giá trị được tính toán của border-top-colorborder-bottom-color đều được đặt thành ButtonFace trong biểu định kiểu tác nhân người dùng hiện là rgba(0, 0, 0, 0.847).
Cho thấy các giá trị màu đã tính toán vẫn khớp với ButtonFace khi ở chế độ tối.
Chế độ tối: Các giá trị đã tính toán của border-top-colorborder-bottom-color đã được đặt thành ButtonFace trong biểu định kiểu tác nhân người dùng hiện là rgba(255, 255, 255, 0.847).

Bản minh hoạ

Bạn có thể xem các hiệu ứng của color-scheme được áp dụng cho một số lượng lớn các phần tử HTML trong bản minh hoạ trên Glitch. Bản minh hoạ có chủ đích cho thấy lỗi vi phạm của WCAG AA và WCAG AAA với các màu đường liên kết nêu trong cảnh báo ở trên.

Bản minh hoạ khi ở chế độ sáng.
Bản minh hoạ đã chuyển thành color-scheme: light.
Bản minh hoạ khi ở chế độ tối.
Bản minh hoạ đã chuyển sang color-scheme: dark. Hãy lưu ý rằng lỗi vi phạm của WCAG AA và WCAG AAA có màu của đường liên kết.

Xác nhận

Thuộc tính CSS color-scheme và thẻ meta tương ứng do Rune Lillesveen triển khai. Rune cũng là đồng biên tập viên về quy cách cấp 1 của mô-đun điều chỉnh màu CSS. Hình ảnh chính của Philippe Leone trên Unsplash.