Sáu cấp độ của dark mode (2024)
(cssence.com)- Tóm tắt 8 cấp độ giúp mở rộng dần phạm vi triển khai dark mode, từ tính năng mặc định của trình duyệt đến media query JavaScript
- Cách đơn giản nhất là chỉ cần khai báo
<meta name="color-scheme" content="light dark">hoặccolor-scheme: light darkđể làm theo tùy chọn color scheme của người dùng - Ở các cấp độ cao hơn, có thể dùng hàm
light-dark(),@media (prefers-color-scheme: dark), và stylesheet tách riêng theo từng scheme để điều chỉnh rộng rãi không chỉ màu sắc mà cả hình ảnh và đổ bóng - Có thể xây dựng bộ chuyển đổi không chỉ theo thiết lập hệ thống của người dùng mà còn cung cấp 3 lựa chọn Automatic·light·dark, đồng thời dùng
:has()và chính phần tử meta thực tế để xác định theme - Bài viết cũng đề cập đến giới hạn về khả năng truy cập của Safari và quan sát cách
prefers-color-schemehoạt động khi in, cho thấy chỉ với các tính năng CSS gần đây cũng đã dễ tích hợp light/dark mode hơn nhiều
Triển khai dark mode theo từng cấp độ
-
Level 1: Barebone
- Có thể kích hoạt phân biệt light/dark ngay cả khi không viết một dòng CSS nào; chỉ cần thêm
<meta name="color-scheme" content="light dark">trong phần head của tài liệu là trình duyệt sẽ bắt đầu làm theo tùy chọn color scheme của người dùng - Về mặt lý thuyết, thứ tự các mục trong thuộc tính
contentcó ý nghĩa; người dùng không chỉ định tùy chọn color scheme sẽ nhận giá trị đầu tiên trong danh sách phân tách bằng khoảng trắng - Hiện tại không có tùy chọn trong hệ điều hành để không chọn color scheme, nên trên thực tế kết quả sẽ quy về scheme khớp với thiết lập hệ điều hành
- Cũng có thể chỉ định một giá trị duy nhất trong
content; khi đó scheme tương ứng sẽ bị áp dụng cưỡng bức mà không xét đến sở thích của người dùng - Thẻ meta này ở mức độ nào đó đóng vai trò là cách làm phía HTML tương ứng với phương pháp CSS ở cấp độ tiếp theo
- Có thể kích hoạt phân biệt light/dark ngay cả khi không viết một dòng CSS nào; chỉ cần thêm
-
Level 2: Basic
- Trong CSS, có thể áp dụng phân biệt light/dark mode bằng khai báo
html { color-scheme: light dark; } - Nếu DOM đã có sẵn thẻ meta thì không cần khai báo này; nếu có thể kiểm soát HTML thì nên dùng thẻ meta để trình duyệt biết chỉ thị từ trước khi phân tích CSS
- Cả hai cách đều cho phép tận dụng kiểu mặc định của user agent và light/dark mode đi kèm trong đó
- Nếu bổ sung CSS tại đây nhưng chủ yếu giới hạn vào việc dùng CSS system colors thì vẫn có thể tạo ra một thiết kế khá gọn gàng
- Không giống thẻ meta luôn áp dụng cho toàn bộ tài liệu, khai báo CSS
color-schemecòn có thể đặt ở vị trí khác ngoài phần tử gốc, và khác biệt này mở ra thêm khả năng tận dụng
- Trong CSS, có thể áp dụng phân biệt light/dark mode bằng khai báo
-
Level 3: Benign
- Có thể điều chỉnh light/dark mode đơn giản bằng hàm màu
light-dark()của CSS được bổ sung tương đối gần đây - Trong ví dụ, nó được dùng như
background-color: light-dark(black, white);vàcolor: light-dark(white, black);; đối số thứ nhất áp dụng cho light mode, còn đối số thứ hai áp dụng cho dark mode - Đối số có thể là màu thực tế hoặc cũng có thể là custom properties được diễn giải thành màu
- Trong toàn bộ bài viết, tại thời điểm viết thì chỉ cấp độ này là hỗ trợ trình duyệt chưa đủ tốt
- Có thể điều chỉnh light/dark mode đơn giản bằng hàm màu
-
Level 4: Bold
- Có thể triển khai chuyển đổi dark mode bằng media query truyền thống
@media (prefers-color-scheme: dark) - Dù truy vấn
lighthaydark, cách này đều cho phép mức tùy biến cao nhất, không bị giới hạn ở việc chỉ đổi màu đơn thuần - Có thể điều chỉnh như giảm bão hòa ảnh bằng bộ lọc trong dark mode, hoặc thay box shadow bằng đường viền ngoài
- Có thể triển khai chuyển đổi dark mode bằng media query truyền thống
-
Level 5: Bisectional
- Media query cũng có thể dùng trong HTML; có thể đặt vào thuộc tính
mediacủa phần tửlinkđể tách stylesheet theo từng scheme - Ví dụ được đưa ra là nối
light.cssvàdark.csslần lượt vớiprefers-color-scheme: lightvàprefers-color-scheme: dark - Nếu phạm vi tùy biến lớn thì cấu trúc file chuyên biệt sẽ phù hợp hơn, và trình duyệt có thể bỏ qua file CSS không khớp với truy vấn nên có thể giảm bớt một mục cần tải xuống
- Media query cũng có thể dùng trong HTML; có thể đặt vào thuộc tính
-
Level 6: Ballistic
- Trong JavaScript, có thể dùng media query color scheme qua
window.matchMedia('(prefers-color-scheme:dark)') - Sau khi truy vấn xem đó là light hay dark giống như các media query khác, có thể thực hiện xử lý mong muốn dựa trên kết quả
- Trong triển khai thực tế, không nhất thiết phải bám vào duy nhất một kỹ thuật ở các cấp trên mà có thể kết hợp nhiều cách
- Trong JavaScript, có thể dùng media query color scheme qua
Bộ chuyển đổi người dùng và các mẫu nâng cao
-
Level 7: Beyond
- Không nhất thiết chỉ phụ thuộc vào tùy chọn hệ thống của người dùng; có thể xây dựng color scheme switcher
- Bộ chuyển đổi này không phải boolean đơn giản mà cần có chế độ Automatic lấy
prefers-color-schemelàm mặc định ban đầu - Khi đặt bộ chuyển đổi lên trên đó, người dùng có thể chọn một trong ba chế độ: Automatic, light, dark
-
Level 8: Beguiling
- Khi triển khai bộ chuyển đổi Level 7, cách phổ biến thường là thêm lớp
.darkhoặc thuộc tính nhưdata-theme="dark"vào phần tử HTML - Thay vào đó, có thể dùng
:has()để truy vấn trực tiếp sự hiện diện của<meta name="color-scheme" content="dark"> - Trong ví dụ, dưới selector
html:has(meta[name="color-scheme"][content="dark"]), các biến CSS như--color-bg,--color-textđược đặt thành giá trị dành cho dark mode - Có thể xác định theme dựa trên phần tử meta thực tế mà không cần lớp hay thuộc tính dữ liệu riêng
- Khi triển khai bộ chuyển đổi Level 7, cách phổ biến thường là thêm lớp
Thảo luận bổ sung và các quan sát
-
Quan sát từ CSS Naked Day
- Sau khi bỏ style, ở gần như mọi trang đã ghé thăm đều dễ thấy sự thiếu vắng dark mode, và điều này dẫn đến việc phân chia các cấp độ dark mode
- Khi xây dựng một trang mới từ đầu và viết style mới, tác giả cho biết với các tính năng CSS gần đây thì việc tích hợp sẵn light/dark mode đã trở nên rất dễ dàng
-
Vấn đề khả năng truy cập của Safari
- Bài viết chỉ ra rằng cho đến tương đối gần đây, Safari không cung cấp màu liên kết dễ truy cập trong dark mode
- Ở CSS Naked Day trước đó, tác giả đã phát hiện vấn đề này, gỡ thẻ meta và chỉ dùng light color scheme
- Sau đó thẻ meta được thêm lại, nhưng tác giả nhận thức rằng với người dùng Safari phiên bản cũ có thể phát sinh suy giảm khả năng truy cập
- Cũng xác nhận rằng trong dark mode của Safari, ô nhập văn bản thiếu đường viền hiển thị rõ ràng
- Chỉ dựa vào style của user agent thì ngay cả khi dùng HTML ngữ nghĩa đúng cũng không thể bảo đảm khả năng truy cập đầy đủ, nên tác giả đang cân nhắc cách giữ lại đủ style cho cả CSS Naked Day trong tương lai
-
In ấn và điều kiện
screen and- Trong ví dụ Bisectional, việc dùng
screen and ...được giải thích là để loại trừ mục tiêu máy in - Với giả định có một stylesheet lõi không phụ thuộc theme hoặc stylesheet in chuyên dụng riêng, tác giả cho rằng nên tách an toàn vì dark mode trên máy in có thể tốn nhiều mực
- Trong thử nghiệm thực tế, ngay cả khi bật dark mode hệ thống rồi in thì đầu ra vẫn chỉ là chữ đen trên giấy trắng, và tác giả quan sát thấy trình duyệt không áp dụng dark mode style đó khi in
- Trong thử nghiệm bổ sung, ở phần xem trước khi in thì
prefers-color-schemeluôn được báo là light; điều này được xác nhận trên Firefox và Chromium - Bài viết cũng có một câu đùa rằng sẽ thật tiếc nếu có máy in dùng giấy đen và mực trắng
- Trong ví dụ Bisectional, việc dùng
1 bình luận
Ý kiến trên Hacker News
userContent.csscủa Firefox là khá ổn