Vấn đề
Chúng ta thường cần kết hợp các tiêu chí lọc thuộc nhiều loại, ví dụ: bộ chọn + truy vấn đa phương tiện, truy vấn đa phương tiện + truy vấn vùng chứa, v.v.
Ví dụ: kết hợp (prefers-color-scheme: dark) với một bộ chọn nhắm đến các chế độ ghi đè bảng phối màu (ví dụ: :root:has(> head > meta[name="color-scheme"][content="dark"]) hoặc :root.dark) để áp dụng một số kiểu nhất định ở chế độ sáng/chế độ tối, bất kể cách thiết lập bảng phối màu.
Cách tiếp cận đơn giản dẫn đến mã trùng lặp:
/* Light mode styles */
.card.featured {
font-weight: 400;
}
#logo-dark {
display: none;
}
@media (prefers-color-scheme: dark) {
/* Dark mode styles */
:root:not(.light) {
.card.featured {
font-weight: 300;
}
#logo-dark {
display: inline;
}
#logo {
display: none;
}
}
}
/* Dark mode styles, again */
:root.dark {
.card.featured {
font-weight: 300;
}
#logo-dark {
display: inline;
}
#logo {
display: none;
}
}
Việc nên làm
Lưu trữ kết quả của bộ lọc kết hợp trên một thuộc tính tuỳ chỉnh, sau đó sử dụng truy vấn kiểu vùng chứa để đặt quy tắc dựa trên thuộc tính đó.
QUAN TRỌNG: Do cách hoạt động của truy vấn vùng chứa, kỹ thuật này chỉ hoạt động nếu chúng ta có thể đặt thuộc tính tuỳ chỉnh trên một đối tượng cấp trên của bất kỳ quy tắc nào phải khớp.
1. Tách logic lựa chọn khỏi các quy tắc được áp dụng
:root {
--color-scheme: light;
@media (prefers-color-scheme: dark) {
--color-scheme: dark;
}
&:has(> head > meta[name="color-scheme"][content="dark"]) {
--color-scheme: dark;
}
&:has(> head > meta[name="color-scheme"][content="light"]) {
--color-scheme: light;
}
}
2. Khoá trên thuộc tính tuỳ chỉnh cho các quy tắc được áp dụng
@container not style(--color-scheme: dark) {
.card.featured {
font-weight: 400;
}
#logo-dark {
display: none;
}
}
@container style(--color-scheme: dark) {
.card.featured {
font-weight: 300;
}
#logo {
display: none;
}
}
3. KHÔNG BẮT BUỘC: Các lớp tiện ích để bật/tắt chế độ hiển thị
Một trường hợp rất phổ biến là bật/tắt chế độ hiển thị dựa trên việc các tiêu chí có khớp hay không.
Các lớp tiện ích phải thắng các kiểu thành phần tuỳ ý (do đó là !important) và display hiển thị của chúng không xác định, vì vậy chúng không thể sử dụng cơ chế ghi đè – hãy kiểm soát chúng bằng not style(...):
@container not style(--color-scheme: dark) {
.if-dark {
display: none !important;
}
}
@container not style(--color-scheme: light) {
.if-light {
display: none !important;
}
}
Bản dự phòng
Có hai loại phương án dự phòng, tuỳ thuộc vào mức độ quan trọng của việc phân nhánh và những yếu tố tạo nên một phương án dự phòng có thể chấp nhận được.
- Đối với việc phân nhánh quan trọng, trong đó tất cả trạng thái phải hoạt động chính xác ngay cả khi không hỗ trợ truy vấn kiểu, bạn không thể sử dụng truy vấn kiểu. Thay vào đó, hãy sử dụng phương pháp đơn giản ở trên, sao chép các quy tắc cho từng trạng thái. Bạn vẫn có thể sử dụng các lớp tiện ích, miễn là các lớp này cũng được xác định theo cách đó.
- Đối với việc phân nhánh không quan trọng, trong đó trạng thái mặc định là chấp nhận được, bạn có thể xác định kiểu cơ sở bên ngoài bất kỳ quy tắc
@containernào và chỉ sử dụng truy vấn kiểu làm cơ chế ghi đè. Điều này giúp giữ lại hầu hết tinh thần của phương pháp này, nhược điểm chính của phương pháp này là việc kết hợp các giá trị mà cơ chế ghi đè đưa ra.
#logo-dark {
display: none;
}
@container style(--color-scheme: dark) {
#logo-dark {
display: inline; /* override */
}
#logo {
display: none;
}
}