bởi Oskar Hane
Trong các phiên bản gần đây của macOS (Mojave) và Windows 10, người dùng đã có thể bật chế độ tối cấp hệ thống. Điều này hoạt động tốt và dễ phát hiện đối với các ứng dụng gốc.
Các trang web đã từng là những ứng dụng kỳ lạ mà tùy thuộc vào nhà xuất bản trang web quyết định người dùng nên sử dụng bảng màu nào. Một số trang web cung cấp hỗ trợ chủ đề. Để người dùng chuyển đổi, họ phải tìm cấu hình cho nó và cập nhật cài đặt theo cách thủ công cho từng trang web riêng lẻ.
Có thể thực hiện việc phát hiện này một cách tự động và để các trang web trình bày một chủ đề tôn trọng sở thích của người dùng không?

Truy vấn phương tiện CSS ‘prefers-color-scheme'
dự thảo
Có một bản nháp truy vấn phương tiện CSS cấp 5 trong đó lược đồ màu ưu tiên được chỉ định. Nó có nghĩa là để phát hiện xem người dùng đã yêu cầu hệ thống sử dụng chủ đề màu sáng hay tối.
Điều này nghe giống như một cái gì đó chúng ta có thể làm việc với! Tuy nhiên, chúng tôi cần cập nhật bất kỳ thay đổi nào đối với bản nháp, vì nó có thể thay đổi bất cứ lúc nào vì đây chỉ là… bản nháp. Các prefers-color-scheme
truy vấn có thể có ba giá trị khác nhau: light
, dark
và no-preference
.
Hỗ trợ trình duyệt web kể từ tháng 3 năm 2019
Hỗ trợ trình duyệt hiện tại là rất bị giới hạn và nó không có sẵn trong bất kỳ bản phát hành ổn định nào của bất kỳ nhà cung cấp nào. Chúng tôi chỉ có thể tận hưởng điều này trong Safari Technology Preview của phiên bản 12.1 và trong Firefox 67.0a1. Điều tuyệt vời là có những tệp nhị phân hỗ trợ nó, vì vậy chúng tôi có thể làm việc với nó và dùng thử trong trình duyệt web. Để biết hỗ trợ trình duyệt hiện tại, hãy xem https://caniuse.com/#search=prefers-color-scheme.
Tại sao chỉ phát hiện CSS là không đủ
Cách tiếp cận phổ biến mà tôi đã thấy cho đến nay là sử dụng cách tiếp cận chỉ CSS và ghi đè các quy tắc CSS cho các lớp nhất định khi truy vấn phương tiện phù hợp.
Một cái gì đó như thế này:
/* global.css */
.themed { display: block; width: 10em; height: 10em; background: black; color: white;}
@media (prefers-color-scheme: light) { .themed { background: white; color: black; }}
Vì điều này hoạt động tốt trong nhiều trường hợp sử dụng nên có những kỹ thuật tạo kiểu không sử dụng CSS theo cách như thế này. Ví dụ: nếu các thành phần được tạo kiểu được sử dụng để tạo chủ đề, thì một đối tượng JS sẽ được thay thế khi chủ đề được thay đổi.
Việc có quyền truy cập vào lược đồ ưu tiên cũng hữu ích cho việc phân tích và ghi đè CSS dễ dự đoán hơn cũng như kiểm soát chi tiết hơn đối với phần tử nào nên theo chủ đề và phần nào không.
Cách tiếp cận JS ban đầu
Trước đây, tôi đã biết rằng bạn có thể thực hiện phát hiện truy vấn phương tiện bằng cách đặt CSS content
của một phần tử thành một giá trị nếu một truy vấn phương tiện phù hợp. Đây chắc chắn là một hack, nhưng nó hoạt động!
Một cái gì đó như thế này:
Vì vậy, khi người dùng tải CSS và truy vấn phương tiện khớp với một trong các bảng màu ở trên, thì content
giá trị tài sản của html
phần tử được đặt thành ‘sáng’ hoặc ‘tối’.
Câu hỏi sau đó là, làm thế nào để chúng ta đọc content
giá trị của html
thành phần?
Chúng ta có thể sử dụng window.getComputedStyle như sau:
Và điều này hoạt động tốt! Cách tiếp cận này là tốt cho một đọc một lần, nhưng nó không phản ứng và tự động cập nhật khi người dùng thay đổi bảng màu hệ thống của họ. Để được cập nhật, cần tải lại trang (hoặc thực hiện đọc ở trên trong một khoảng thời gian).
Cách tiếp cận JS phản ứng
Làm thế nào chúng ta có thể biết khi người dùng thay đổi bảng màu hệ thống? Có bất kỳ sự kiện chúng ta có thể lắng nghe?
Vâng có!
Có window.matchMedia có sẵn trong các trình duyệt web hiện đại.
Điều tuyệt vời với matchMedia
là chúng ta có thể đính kèm một người nghe vào nó sẽ được gọi bất cứ khi nào trận đấu thay đổi.
Người nghe sẽ được gọi với một đối tượng chứa thông tin nếu truy vấn phương tiện bắt đầu khớp hoặc nếu nó ngừng khớp. Với thông tin này, chúng ta có thể bỏ qua CSS hoàn toàn và chỉ làm việc với JS.
Cách tiếp cận này hoạt động rất tốt trong các trình duyệt web được hỗ trợ và chỉ chọn không tham gia nếu window.matchMedia
không được hỗ trợ.
móc phản ứng
Vì chúng tôi đang sử dụng React trong trình duyệt neo4j, nên tôi đã viết phần này dưới dạng hook React tùy chỉnh để dễ dàng sử dụng lại trong tất cả các ứng dụng của chúng tôi và phù hợp với hệ thống React.
Đó là mã nhiều hơn một chút so với bằng chứng khái niệm ngắn đầu tiên. Chúng tôi có khả năng phát hiện lỗi tốt hơn và chúng tôi cũng loại bỏ các trình xử lý sự kiện khi hook không được gắn kết.
Trong trường hợp sử dụng của chúng tôi, người dùng có thể chọn ghi đè lược đồ được tự động phát hiện bằng một thứ khác (ví dụ: chúng tôi cung cấp một chủ đề được phác thảo, thường được sử dụng khi thuyết trình).
Và sau đó sử dụng nó như thế này trong lớp ứng dụng:
Phần cuối cùng phụ thuộc vào cách tạo chủ đề trong ứng dụng của bạn. Trong ví dụ trên, đối tượng dữ liệu chủ đề được chuyển vào một trình cung cấp ngữ cảnh để cung cấp đối tượng này trong toàn bộ ứng dụng React.
Kết quả cuối cùng
Đây là một gif với kết quả cuối cùng, và như bạn có thể thấy, nó diễn ra ngay lập tức.

suy nghĩ cuối cùng
Đây là một thử nghiệm thú vị được thực hiện trong cái gọi là “Ngày phòng thí nghiệm” mà chúng tôi có trong nhóm UX tại Neo4j. Giai đoạn đầu của thông số kỹ thuật và (do đó) việc thiếu hỗ trợ trình duyệt không chứng minh được điều này để biến nó thành bất kỳ sản phẩm nào. Nhưng hỗ trợ có thể đến sớm hơn sau này.
Ngoài ra, chúng tôi vận chuyển một số sản phẩm dựa trên Electron và có một electron.systemPreferences.isDarkMode()
có sẵn ở đó…
Giới thiệu về tác giả
Oskar Hane là trưởng nhóm / kỹ sư cao cấp tại Neo4j.
Anh ấy làm việc trên nhiều thư viện mã và ứng dụng dành cho người dùng cuối của Neo4j: đồng thời là tác giả của hai cuốn sách công nghệ.
Theo dõi Oskar trên twitter: @oskarhane