Tổng quan
Thẻ nhóm một phần nội dung có liên quan hoặc một lựa chọn. Đây là một mẫu hình ảnh, không phải là mô hình ngữ nghĩa hoặc tương tác cố định, vì vậy, hãy giữ nguyên ý nghĩa của nội dung và sử dụng kiểu tương tác gốc phù hợp với mục đích của nội dung đó.
Nguyên tắc
Chọn ngữ nghĩa cho nội dung và hoạt động tương tác của nội dung một cách riêng biệt:
- sử dụng
<article>làm gốc thẻ, cho dù thẻ đó có liên kết đến một đích đến hay không; - sử dụng đường liên kết gốc để điều hướng. Khi toàn bộ thẻ là một đích đến, một đường liên kết duy nhất có thể gói
<article>chỉ khi thẻ không chứa thành phần tương tác nào khác (a,button,input,select,textarea); - giữ các đường liên kết và nút cho các hành động độc lập dưới dạng các chế độ điều khiển gốc riêng biệt;
- sử dụng nút chọn hoặc hộp đánh dấu có
<label>liên kết hoặcoptiontrong<select>gốc khi thẻ là một lựa chọn.
Sắp xếp nội dung nghe nhìn, tiêu đề, nội dung hỗ trợ và hành động theo thứ tự nguồn hợp lý; không sử dụng CSS order để làm trái thứ tự này (xem phần Bố cục CSS và thiết kế đáp ứng).
Triển khai
Giữ mã đánh dấu ở mức tối thiểu và cho phép bộ chọn CSS nhận dạng từng vùng, nhờ đó, các thẻ đơn giản vẫn đơn giản và các thẻ thông tin chi tiết vẫn có thể thực hiện được. Một thẻ có tối đa 4 vùng, theo thứ tự nguồn này và bạn có thể bỏ qua bất kỳ vùng nào trong số đó. Vùng là phần tử con trực tiếp của thẻ, không được nhóm trong các phần tử bao bọc như .card__body, điều này ngăn việc đặt và tạo kiểu cho các vùng theo bộ chọn. Một vùng có một phần tử duy nhất chính là phần tử đó, không được gói: một đoạn văn bản riêng lẻ là <p>. Chỉ sử dụng trình bao bọc khi một vùng chứa nhiều phần tử.
- Nội dung nghe nhìn:
<img>,<picture>,<video>hoặc<svg>là phần tử con đầu tiên. Chỉ thêm lớp.mediavào nội dung chủ chốt tuỳ ý không phải là một trong các phần tử đó và không bao giờ gói<img>thuần tuý trong phần tử.media. - Tiêu đề: một tiêu đề riêng. Chỉ sử dụng
<hgroup>khi tiêu đề có phụ đề hoặc dòng giới thiệu và<header>khi khu vực có nhiều hơn một tiêu đề, chẳng hạn như dòng ghi tên tác giả hoặc huy hiệu. Khi thẻ có đích đến chính, đường liên kết sẽ nằm trong tiêu đề. - Nội dung: một
<p>,<ul>hoặc<dl>đứng riêng lẻ. Khi nội dung có nhiều phần tử, chẳng hạn như nhiều đoạn văn hoặc một đoạn văn cộng với một danh sách, hãy nhóm các phần tử đó vào một<div>để vùng đó là một mục lưới duy nhất. - Chân trang: một
<footer>chứa các thao tác độc lập dưới dạng đường liên kết và nút gốc. Đường liên kết "đọc thêm" có thể dùng chung URL của đường liên kết tiêu đề, nhưng hãy đặt cho đường liên kết đó một tên thành phần hỗ trợ tiếp cận mang tính mô tả và bắt đầu bằng văn bản hiển thị, sử dụng văn bản bị ẩn về mặt hình ảnh (ví dụ:Read more<span> about poached eggs</span>), vì các đường liên kết "đọc thêm" giống hệt nhau sẽ không rõ ràng trong danh sách đường liên kết của trình đọc màn hình. Đừng thêm các đường liên kết khác ở chân trang lặp lại URL của tiêu đề.
Thẻ đơn giản nhất là một <article> chứa tiêu đề và đoạn văn. Chọn mẫu đường liên kết và hành động phù hợp với hành vi của thẻ; xem Mô hình tương tác.
Đối với hình ảnh hoặc video trên thẻ cần lấp đầy một khu vực có tỷ lệ cố định, hãy đặt aspect-ratio và object-fit: cover trên chính <img> hoặc <video> để lấp đầy khu vực đó mà không bị méo (có thể xảy ra hiện tượng cắt ảnh). Chỉ sử dụng aspect-ratio của vùng chứa .media cho nội dung chủ chốt khác. Nếu không, hãy giữ nguyên tỷ lệ nội tại của nội dung nghe nhìn. Cung cấp văn bản thay thế phù hợp cho hình ảnh chứa thông tin; sử dụng alt="" cho hình ảnh trang trí.
Điều chỉnh theo không gian có sẵn
Bố cục dựa trên không gian có sẵn của thẻ, chứ không phải khung nhìn. Để điều chỉnh các thành phần con của thẻ (nội dung nghe nhìn, văn bản, hành động), hãy đặt thẻ làm vùng chứa kích thước (container-type: inline-size) và viết các quy tắc @container cho các thành phần con của thẻ. Tránh định cỡ từ lưới hoặc danh sách gốc: chiều rộng thực tế của thẻ có thể phụ thuộc vào số lượng cột, khoảng trống, v.v., khiến các điểm ngắt dựa trên thành phần gốc bị nhiễu.
Trong vùng chứa hẹp, hãy xếp chồng các vùng theo thứ tự nguồn. Trong vùng chứa rộng, hãy đặt nội dung nghe nhìn vào một cột bên cạnh các vùng khác, nhưng chỉ dành cho những thẻ có nội dung nghe nhìn: đặt phạm vi cho các quy tắc đó bằng :has() trên phần tử con của nội dung nghe nhìn (ví dụ: .card:has(> img)) để các định nghĩa cột và vị trí grid-column không bao giờ áp dụng cho thẻ không có nội dung nghe nhìn. Thẻ không có nội dung nghe nhìn sẽ giữ nguyên một cột ở mọi chiều rộng và không được dành riêng một cột nội dung nghe nhìn trống.
Căn chỉnh thẻ trong lưới
Khi các thẻ trong một hàng cần có cùng chiều cao cho các vùng, hãy sử dụng subgrid: đặt mỗi thẻ trải dài trên bốn dải hàng dùng chung (nội dung nghe nhìn, tiêu đề, nội dung, chân trang) và đặt các vùng theo bộ chọn phần tử, coi mọi thứ không phải là nội dung nghe nhìn, tiêu đề hoặc <footer> là nội dung. Một thẻ bỏ qua một khu vực sẽ để trống dải của khu vực đó, vì vậy, các khu vực còn lại vẫn xếp hàng với các thẻ lân cận. Mỗi dải chứa một mục trong lưới, vì vậy, chỉ gói vùng nội dung trong <div> khi vùng đó có nhiều phần tử và các thẻ dùng chung dải. Những thẻ không được căn chỉnh với các thẻ đồng cấp không cần trình bao bọc cũng như lưới phụ.
Mô hình tương tác
Thẻ nội dung
Sử dụng <article> làm gốc thẻ. Giữ các đường liên kết và nút dưới dạng các thành phần điều khiển gốc riêng biệt.
Thẻ một điểm đến
Khi toàn bộ thẻ là một đích đến và không có hành động độc lập, hãy sử dụng một đường liên kết gốc. Đường liên kết có thể bao bọc <article>. Đừng lồng các đường liên kết, nút hoặc thành phần điều khiển biểu mẫu khác vào bên trong đường liên kết và hãy giữ cho mọi văn bản "đọc thêm" ở dạng <p> hoặc <span> thuần tuý. Vì tên thành phần hỗ trợ tiếp cận của đường liên kết là toàn bộ văn bản của thẻ, nên hãy giữ cho nội dung ngắn gọn; nếu thẻ có nhiều văn bản hoặc các thao tác khác, hãy sử dụng mẫu đường liên kết kéo dài bên dưới để chỉ có tiêu đề là đường liên kết:
<a href="/recipes/poached-eggs">
<article class="card">
<h3>Poached eggs</h3>
<p>Two poached eggs served on toasted sourdough.</p>
</article>
</a>
Thẻ có thể nhấp với các thao tác độc lập
Nếu thao tác nhấp vào thẻ kích hoạt một hành động thay vì điều hướng, hãy sử dụng <button> thay vì đường liên kết.
Khi thẻ nội dung liên kết đến một đích đến chính, đồng thời chứa các thành phần tương tác khác và cần có thể nhấp vào toàn bộ thẻ:
- Sử dụng một lựa chọn chọn sử dụng duy nhất, trên chính đường liên kết chính: đặt
.card-linktrên đúng một đường liên kết cho mỗi thẻ (đường liên kết tiêu đề). Chân trang và các đường liên kết khác không bao giờ nhận được, nếu không thì mỗi đường liên kết sẽ kéo dài lớp phủ riêng và đường liên kết cuối cùng sẽ chiếm toàn bộ thẻ. - Liên kết tiêu đề và kéo dài vùng nhấn của con trỏ trên thẻ bằng
::after
.card:has(a.card-link) {
position: relative;
}
.card a.card-link::after {
content: "";
position: absolute;
inset: 0;
}
- Nâng cao các thành phần tương tác bằng
position: relative; z-index: 1để các thành phần đó vẫn hoạt động được. Nhắm đến các loại phần tử (ví dụ:a, button) thay vì yêu cầu chọn sử dụng thông qua các lớp. - KHÔNG áp dụng
z-indexcho toàn bộ vùng chứa vì điều đó sẽ khiến chúng ghi lại các sự kiện con trỏ không tạo ra bất kỳ hành động nào.
.card:has(a.card-link) {
/* Keep other interactive elements above the overlay */
a:not(.card-link), button, input, x-button {
position: relative;
z-index: 1;
}
}
- Tạo kiểu cho chính thẻ khi di chuột/tiêu điểm, thay vì đường liên kết được kéo dài:
.card {
a.card-link {
&:focus-visible {
outline: none; /* Draw it on the card instead */
}
}
&:has(a.card-link:focus-visible) {
/* Focus ring */
}
&:has(a.card-link:hover) {
/* Hover styles */
}
}
Thẻ lựa chọn
Đối với các thẻ đại diện cho các lựa chọn được xác định trước, hãy sử dụng <label class="card"> với hộp đánh dấu hoặc nút chọn làm phần tử con trực tiếp.
Tạo kiểu cho thẻ đã chọn bằng :has(:checked). Tuyệt đối không thay đổi các thuộc tính ảnh hưởng đến bố cục như border-width, padding hoặc font-weight khi lựa chọn, vì thẻ và các thành phần lân cận sẽ nhảy; hãy nhấn mạnh bằng outline, box-shadow hoặc đường viền trong suốt chỉ thay đổi màu:
.card {
border: 2px solid transparent;
&:has(> :checked) {
border-color: var(--accent);
}
}
Hộp đánh dấu hoặc nút chọn hiển thị chính là một chỉ báo không màu cho lựa chọn, vì vậy, chỉ cần thay đổi màu là đủ. Nếu chế độ kiểm soát bị ẩn (giữ cho chế độ này có thể lấy tiêu điểm và nằm trong cây hỗ trợ tiếp cận, không bao giờ display: none), hãy thêm một chỉ báo không màu không ảnh hưởng đến bố cục, chẳng hạn như biểu tượng dấu kiểm hoặc outline dày hơn.
Khi các lựa chọn thuộc về một bộ chọn thả xuống có các lựa chọn được bố trí dưới dạng thẻ, hãy sử dụng <select> gốc với appearance: base-select và tạo kiểu cho các phần tử ::picker(select) và <option> thay vì thay thế lựa chọn bằng thẻ <div>; hãy xem phần Bố cục bộ chọn tuỳ chỉnh để biết thêm thông tin chi tiết và các phương án dự phòng.