Sử dụng truy vấn kiểu (@container style()) để kích hoạt các biến thể theo bối cảnh mà không cần cố định giá trị trong mã cho nội dung tạo ra hoặc phản ứng với từng bối cảnh. Điều này giúp giảm sự kết hợp hệ thống thiết kế, đồng thời cải thiện khả năng mở rộng và đóng gói thành phần.
Ví dụ: quy tắc section.featured { --surface: featured } có thể đánh dấu một bối cảnh và trang đích cũng có thể mặc định sử dụng bối cảnh đó thông qua main { --surface: featured }. Sau đó, các thành phần sẽ chọn phản ứng với --surface: featured: thẻ cho thấy huy hiệu khuyến mãi, nút mặc định là biến thể được lấp đầy, v.v.
Truy vấn kiểu cho phép cả hai bên tách biệt nhau: các nền tảng nổi bật không bao giờ đặt tên cho các phần tử thích ứng với chúng và các thành phần không bao giờ kiểm tra nội dung đã tạo ra ngữ cảnh. Bạn có thể mở rộng riêng từng bên (thành phần mới, nền tảng nổi bật mới) mà không ảnh hưởng đến bên còn lại. Bộ chọn con cháu (ví dụ: .featured .button) buộc phải làm ngược lại: bộ chọn phải mã hoá cả hai bên của mối quan hệ và phải thay đổi bất cứ khi nào một trong hai bên thay đổi.
Trường hợp sử dụng hướng dẫn này
Hướng dẫn này đề cập đến các thay đổi về hành vi: một thành phần quyết định nội dung cần hiển thị, cách tự sắp xếp hoặc biến thể cần trình bày để phản hồi bối cảnh của thành phần đó – ẩn hoặc hiện huy hiệu, chuyển đổi hướng bố cục hoặc hoán đổi biến thể nút.
Nếu bạn cần thay đổi ở cấp mã thông báo (chế độ mật độ, giao diện hoặc các mã thông báo cấp cao hơn khác giúp thay đổi đồng nhất các giá trị như khoảng đệm và màu sắc trên nhiều thành phần), hãy xem phần Khả năng phản ứng của mã thông báo thiết kế.
Chọn công cụ phù hợp
Hãy sử dụng truy vấn kiểu khi cả hai bên của mối quan hệ theo bối cảnh có thể thay đổi độc lập – các phần tử mới có thể bắt đầu tạo bối cảnh hoặc các thành phần mới có thể bắt đầu phản ứng với bối cảnh đó. Sự gián tiếp này mang lại lợi ích về khả năng mở rộng và đóng gói, đồng thời các truy vấn kiểu vượt qua ranh giới DOM bóng mà bộ chọn con cháu không thể làm được. Khi không cần đến tính linh hoạt đó, hãy ưu tiên công cụ đơn giản hơn:
- Bộ chọn con cháu (
.toolbar .button): mối quan hệ cố định, một lần, không thể sử dụng lại hoặc mở rộng. YAGNI áp dụng — không thêm sự gián tiếp mà bạn sẽ không sử dụng. - Truy vấn kích thước (
@container (min-width: …)): thay đổi bố cục và mật độ do không gian có sẵn, không phải trạng thái ngữ nghĩa. - Truy vấn kiểu (
@container style(…)): trạng thái ngữ nghĩa – những gì một thành phần sẽ hiển thị, sắp xếp hoặc trình bày trong một bối cảnh nhất định.
Chỉ thị triển khai
- Xác định cờ ngữ cảnh ngữ nghĩa bằng thuộc tính tuỳ chỉnh CSS trên vùng chứa.
- KHÔNG đặt
container-typecho truy vấn kiểu; các truy vấn này truy vấn các thuộc tính tuỳ chỉnh kế thừa trên đối tượng cấp trên gần nhất và không yêu cầu ngữ cảnh chứa rõ ràng. - BẮT BUỘC: Sử dụng
@container style(--property: value)để áp dụng kiểu có điều kiện cho các phần tử con. Cụm từ tìm kiếm kiểu không thể khớp với phần tử mà thuộc tính được đặt, mà chỉ khớp với các phần tử con của phần tử đó. - NÊN ưu tiên truy vấn kiểu hơn bộ chọn con cháu khi mối quan hệ phải duy trì ranh giới DOM bóng/thành phần chéo hoặc có thể mở rộng (xem phần Chọn công cụ phù hợp ở trên) — nhưng hãy giữ bộ chọn con cháu cho các mối quan hệ cố định, một lần mà sự gián tiếp không mang lại lợi ích gì.
Ví dụ về cách triển khai
/* 1. Set the context on a layout container */
.featured {
--surface: featured; /* Semantic context flag for children */
}
/* 2. Component reacts to inherited flag */
.button {
/* Default: Outlined informational style */
background: transparent;
border: 1px solid currentColor;
}
.badge {
/* Default: Hidden — only revealed in featured surfaces */
display: none;
}
@container style(--surface: featured) {
.button {
/* Automatic switch to Filled promotional style */
background: var(--brand-accent);
color: white;
border: none;
}
.badge {
/* Reveal decorative elements only in featured context */
display: block;
}
}
Chiến lược dự phòng
Cho đến khi truy vấn kiểu vùng chứa được cung cấp rộng rãi, hãy xếp lớp chúng dưới dạng một cải tiến tăng dần: cung cấp một bộ chọn mặc định hoạt động ở mọi nơi và cho phép truy vấn kiểu ghi đè khi được hỗ trợ. Sử dụng :where() trên bộ chọn ngữ cảnh để truy vấn kiểu (cùng độ cụ thể, sau đó theo thứ tự nguồn) tự động thắng.
/* Default styles — work everywhere */
.button {
background: transparent;
border: 1px solid currentColor;
}
.badge {
display: none;
}
/* Selector-based contextual styles — broad browser support */
:where(.featured) .button {
background: var(--brand-accent);
color: white;
border: none;
}
:where(.featured) .badge {
display: block;
}
/* Progressive enhancement: style queries override when supported */
@container style(--surface: featured) {
.button {
background: var(--brand-accent);
color: white;
border: none;
}
.badge {
display: block;
}
}
Phương án dự phòng của bộ chọn liên kết kiểu theo bối cảnh với tên lớp, từ đó liên kết thành phần với vị trí DOM của thành phần đó. Sau khi các truy vấn kiểu được hỗ trợ rộng rãi, bạn có thể xoá quy tắc :where().