Sáu cấp độ triển khai Dark Mode: Từ cơ bản đến nâng cao cho lập trình viên
Bài viết khám phá các phương pháp triển khai chế độ tối (Dark Mode) trong phát triển web, từ việc sử dụng thẻ meta đơn giản đến các kỹ thuật CSS và JavaScript phức tạp. Đây là hướng dẫn hữu ích giúp các nhà phát triển tối ưu hóa trải nghiệm người dùng theo sở thích màu sắc của hệ điều hành.

Trong ngày CSS Naked Day năm nay, một sự thật thú vị đã được phát hiện: khi các tệp样式 (styles) bị gỡ bỏ, hầu hết các trang web đều mất đi chế độ tối. Điều này đặt ra câu hỏi về cách chúng ta triển khai Dark Mode và liệu có những cấp độ khác nhau trong việc thực hiện nó hay không. Thực tế là có, và bài viết này sẽ phân tích sáu cấp độ (và hơn thế nữa) để chuyển đổi giao diện màu sắc trên website.
Level 1: Cơ bản nhất (Barebone)
Đây là cấp độ đơn giản nhất nhưng lại bị bỏ quên trên nhiều trang web. Bạn có thể kích hoạt tính năng phân biệt chế độ sáng/tối mà không cần viết một dòng CSS nào, chỉ cần sử dụng thẻ meta trong phần head của tài liệu HTML:
<meta name="color-scheme" content="light dark">
Khi trang web có thẻ này, trình duyệt sẽ biết rằng nó cần tuân theo sở thích về giao diện màu sắc của người dùng từ hệ điều hành. Thứ tự các giá trị trong thuộc tính content rất quan trọng về mặt lý thuyết, nhưng trong các hệ điều hành hiện đại, người dùng gần như luôn phải chọn một trong hai chế độ, nên trình duyệt sẽ tự động áp dụng chế độ phù hợp.
Level 2: Cơ bản với CSS (Basic)
Chúng ta chuyển sang cách tiếp cận bằng CSS để phân biệt chế độ sáng và tối.
html {
color-scheme: light dark;
}
Nếu bạn đã sử dụng thẻ meta ở Level 1, bạn có thể không cần khai báo này. Tuy nhiên, việc sử dụng thẻ meta vẫn được khuyến khích vì nó giúp trình duyệt biết trước về chỉ thị màu sắc trước khi bất kỳ CSS nào được phân tích. Cả hai cách này đều cho phép bạn tận dụng các kiểu mặc định của trình duyệt (user agent default styles) cùng với các màu hệ thống (system colors) để tạo ra giao diện gọn gàng.
Level 3: Ôn hòa (Benign)
Đây là cấp độ sử dụng một tính năng mới hơn của CSS: hàm light-dark().
html {
background-color: light-dark(black, white);
color: light-dark(white, black);
}
Hàm này nhận hai đối số là màu sắc. Đối số đầu tiên được áp dụng cho chế độ sáng và đối số thứ hai cho chế độ tối. Bạn có thể sử dụng màu trực tiếp hoặc các biến CSS (custom properties). Lưu ý rằng mức độ hỗ trợ trình duyệt cho tính năng này có thể chưa hoàn hảo vào thời điểm hiện tại, nhưng nó là xu hướng trong tương lai.
Level 4: Mạnh mẽ (Bold)
Chúng ta quay lại với phương pháp truyền thống nhưng mạnh mẽ: Media Query.
@media (prefers-color-scheme: dark) {
html {
background-color: black;
color: white;
}
}
Media query cho phép tùy biến hóa tối đa vì bạn không bị giới hạn chỉ ở việc thay đổi màu sắc. Bạn có thể thêm bộ lọc để giảm độ bão hòa của hình ảnh, thay đổi đổ bóng hộp (box shadow) bằng đường viền (outline), hoặc bất kỳ thay đổi nào khác.
Level 5: Tách biệt (Bisectional)
Bạn cũng có thể sử dụng media query trực tiếp trong HTML thông qua thuộc tính media, cho phép tạo các tệp biểu định kiểu (style sheets) riêng biệt cho từng giao diện.
<link rel="stylesheet" href="dark.css" media="(prefers-color-scheme: dark)">
Việc sử dụng các tệp riêng biệt có ý nghĩa nếu bạn thực hiện nhiều tùy biến. Trình duyệt có thể bỏ qua bất kỳ tệp CSS nào không khớp với truy vấn, giúp giảm lượng dữ liệu cần tải xuống.
Mô phỏng Level 6
Level 6: Can thiệp bằng JavaScript (Ballistic)
Tất nhiên, JavaScript cũng có vai trò trong việc này. Bạn có thể sử dụng hàm matchMedia để truy vấn chế độ sáng hoặc tối, giống như bất kỳ media query nào khác.
const isDarkScheme = window.matchMedia('(prefers-color-scheme:dark)');
Sau đó, bạn có thể thực hiện bất kỳ logic nào dựa trên kết quả này. Trong thực tế, các nhà phát triển thường kết hợp linh hoạt các kỹ thuật từ tất cả các cấp độ nêu trên.
Level 7: Vượt ra ngoài giới hạn (Beyond)
Bạn không nhất thiết phải phụ thuộc hoàn toàn vào sở thích của người dùng; bạn có thể xây dựng một công cụ chuyển đổi giao diện (color scheme switcher).
Tuy nhiên, hãy cẩn thận: sở thích cho chế độ sáng hoặc tối không phải là một trạng thái boolean (đúng/sai). Ban đầu, bạn muốn mặc định là "Tự động" (Automatic), tức là tuân theo prefers-color-scheme. Bằng cách xây dựng bộ chuyển đổi giao diện trên nền tảng đó, bạn cho phép người dùng chọn một trong ba chế độ: Sáng, Tối hoặc Tự động.
Level 8: Hấp dẫn và hiện đại (Beguiling)
Khi các nhà phát triển web tạo bộ chuyển đổi giao diện ở Level 7, họ thường thêm một lớp như .dark vào phần tử HTML hoặc thuộc tính data-theme="dark".
Thực tế, chúng ta không cần làm vậy nữa vì chúng ta có thể sử dụng bộ chọn :has() để truy vấn trực tiếp.
html:has(meta[name="color-scheme"][content="dark"]) {
--color-bg: black;
--color-text: white;
}
Đây là một kỹ thuật rất thú vị cho phép CSS phản ứng trực tiếp với sự thay đổi của thẻ meta mà không cần can thiệp quá nhiều vào JavaScript hay thêm các lớp thừa thãi.



