Ngày xuất bản: 6 tháng 11 năm 2024
Kể từ Chrome 131, bạn có nhiều lựa chọn hơn để tạo kiểu cho cấu trúc của các phần tử <details>
và <summary>
. Giờ đây, bạn có thể sử dụng các phần tử này khi tạo tiện ích thông tin công bố hoặc tiện ích xếp nếp.
Cụ thể, các thay đổi được giới thiệu trong Chrome 131 cho phép sử dụng thuộc tính display
trên các phần tử này và thêm phần tử giả ::details-content
để tạo kiểu cho phần mở rộng và thu gọn.
Hỗ trợ trình duyệt
Thiết lập display
trên phần tử <details>
Trước đây, bạn không thể thay đổi loại hiển thị của phần tử <details>
. Giờ đây, quy định hạn chế này đã được nới lỏng, cho phép bạn sử dụng bố cục lưới hoặc bố cục flex trên phần tử <details>
.
Trong ví dụ sau, bảng điều khiển độc quyền bao gồm một số phần tử <details>
được đặt cạnh nhau. Khi mở rộng một trong các phần tử <details>
, nội dung của phần tử đó sẽ được đặt bên cạnh <summary>
.
Bản minh hoạ
Đang ghi
Bạn có thể thực hiện việc này bằng cách sử dụng bố cục flex trên phần tử <details>
, sử dụng CSS sau:
details {
display: flex;
flex-direction: row;
}
Các giá trị hiển thị khác cũng được phép, chẳng hạn như grid
.
Lưu ý về cách sử dụng display: inline
Giá trị display
có thể có kết quả không mong muốn là inline
. Không phải vì không hoạt động mà là do các giới hạn của trình phân tích cú pháp HTML.
Khi đặt phần tử <details>
vào trong một đoạn văn bản, trước tiên, trình phân tích cú pháp HTML sẽ buộc đóng đoạn văn bản đang mở, như được xác định trong mục 13.2.6.4.7 của Tiêu chuẩn HTML:
Thẻ bắt đầu có tên thẻ là một trong các thẻ sau: "address", "article", "aside", "blockquote", "center", "details", "dialog", "dir", "div", "dl", "fieldset", "figcaption", "figure", "footer", "header", "hgroup", "main", "menu", "nav", "ol", "p", "search", "section", "summary", "ul"
Nếu ngăn xếp các phần tử đang mở có phần tử p trong phạm vi nút, hãy đóng phần tử p. Chèn một phần tử HTML cho mã thông báo.
Do đó, <details>
sẽ chảy theo hướng khối, bất kể bạn đã đặt display: inline
hay chưa.
Ví dụ: mã đánh dấu sau
<p>Hello <details>…</details> world</p>
Sau khi phân tích cú pháp, sẽ trở thành:
<p>Hello </p><details>…</details> world<p></p>
Bạn có thể tự xem trong bản minh hoạ này bằng cách kiểm tra mã đánh dấu được phân tích cú pháp bằng Công cụ của Chrome cho nhà phát triển.
Xin lưu ý rằng điều này chỉ áp dụng cho việc lồng <details>
bên trong <p>
. Bạn có thể sử dụng display: inline
trên <details>
bên trong <div>
.
Phần tử giả ::details-content
Trong trình duyệt, phần tử <details>
được triển khai bằng Shadow DOM. Phần tử này chứa một <slot>
cho phần tóm tắt (có phần tử con tóm tắt mặc định) và một <slot>
cho tất cả nội dung còn lại, nghĩa là tất cả phần tử con của phần tử <details>
ngoại trừ phần tử <summary>
.
<details>
↳ #shadow-root (user-agent)
<slot id="details-summary">
<summary>Details</summary>
<!-- The summary goes here -->
</slot>
<slot id="details-content">
<!-- All content goes here -->
</slot>
</details>
Ngoài việc sử dụng nhiều loại màn hình hơn trên <details>
, giờ đây, bạn có thể nhắm mục tiêu đến khung nội dung bằng phần tử giả ::details-content
. Bạn có thể sử dụng lớp mô phỏng này để tạo kiểu cho vùng chứa gói nội dung của phần tử <details>
.
details::details-content {
border: 5px dashed hotpink;
}
Để chỉ áp dụng kiểu đã đặt khi phần tử <details>
ở trạng thái mở, hãy thêm bộ chọn [open]
vào phần tử đó.
[open]::details-content {
border: 5px dashed hotpink;
}
Bạn chỉ nên áp dụng kiểu cho phần tử ::details-content
giả khi phần tử <details>
ở trạng thái [open]
.
Bản minh hoạ
Đang ghi
Loại display
của ::details-content
được đặt thành block
trong trang tính kiểu UA, trong khi trước đây là display: contents
. Thay đổi này có thể gây bất lợi cho bạn trong một số trường hợp, chẳng hạn như nội dung được công bố dựa vào height: 100%
. Nếu gặp vấn đề này, bạn có thể giải quyết bằng cách đặt loại display
về contents
, như sau: details[open]::details-content { display: contents; }
.
Tạo ảnh động cho phần tử giả ::details-content
Bạn có thể tạo ảnh động cho nội dung của phần tử <details>
khi phần tử này mở rộng. Trong ví dụ sau, chiều rộng sẽ tạo ảnh động từ 0px
đến 300px
.
::details-content {
transition: width 0.5s ease, content-visibility 0.5s ease allow-discrete;
width: 0;
}
[open]::details-content {
width: 300px;
}
Ngoài việc chuyển đổi width
, bạn cũng cần chuyển đổi thuộc tính content-visibility
. Lý do là giá trị của thuộc tính này thay đổi giữa trạng thái chưa mở và đã mở, như được xác định trong trang tính kiểu User-Agent. Vì thuộc tính đó là một thuộc tính có thể tạo ảnh động riêng biệt, nên bạn cần có từ khoá allow-discrete
để thuộc tính đó hoạt động.
Thêm vào bản minh hoạ độc quyền về accordion đã chia sẻ trước đó, kết quả sẽ như sau:
Bản minh hoạ
Đang ghi
height
cũng có thể là ảnh động. Để tạo ảnh động cho height: auto
, bạn cần sử dụng interpolate-size
hoặc calc-size()
. Ngoài ra, để nội dung không bị tràn ra khỏi ::details-content
giả lập, hãy áp dụng overflow: clip
cho nội dung đó.
::details-content {
transition: height 0.5s ease, content-visibility 0.5s ease allow-discrete;
height: 0;
overflow: clip;
}
/* Browser supports interpolate-size */
@supports (interpolate-size: allow-keywords) {
:root {
interpolate-size: allow-keywords;
}
[open]::details-content {
height: auto;
}
}
/* Fallback for browsers with no interpolate-size support */
@supports not (interpolate-size: allow-keywords) {
[open]::details-content {
height: 150px;
overflow-y: scroll; /* In case the contents should be taller than 150px */
}
}
Bạn có thể xem mã đang hoạt động trong bản minh hoạ sau đây, lấy cảm hứng từ ngăn xếp của Material UI. Nội dung của mỗi phần tử <details>
sẽ tạo hiệu ứng ảnh động đẹp mắt.
Bản minh hoạ
Đang ghi
Trong các trình duyệt không hỗ trợ ::details-content
, thành phần này vẫn hoạt động tốt. Khách truy cập chỉ không thấy ảnh động.
Phát hiện tính năng
Để phát hiện tính năng hỗ trợ cho lớp mô phỏng ::details-content
trong CSS, hãy sử dụng đoạn mã sau.
@supports selector(::details-content) {
…
}
Bạn cũng có thể sử dụng tính năng phát hiện này làm cơ sở kiểm tra để biết trình duyệt mà khách truy cập đang sử dụng có hỗ trợ các giá trị hiển thị bổ sung hay không.
Những điểm cần cân nhắc về khả năng hỗ trợ tiếp cận
Việc giới thiệu phần tử giả ::details-content
và khả năng thay đổi loại màn hình không ảnh hưởng đến khả năng hỗ trợ tiếp cận của phần tử <details>
.
Giống như trước đây, ít nhất là trong các trình duyệt dựa trên Chromium và theo Tiêu chuẩn HTML, phần tử <details>
có thể tìm kiếm và tự động mở rộng khi trình duyệt cố gắng cuộn đến nội dung ẩn của phần tử đó để phản hồi thao tác tìm kiếm trong trang, ScrollToTextFragment và điều hướng mảnh phần tử. Điều này không thay đổi.
Tuy nhiên, trước khi sử dụng các trình đơn accordion độc quyền, hãy cân nhắc xem điều này có hữu ích hay gây hại cho người dùng. Mặc dù việc sử dụng một trình đơn accordion độc quyền giúp giảm lượng không gian hình ảnh mà nội dung chiếm dụng, nhưng người dùng có thể phải mở nhiều mục để xem hết thông tin. Điều này có thể gây khó chịu cho những người dùng muốn xem nhiều mục cùng một lúc.
Còn việc tạo kiểu cho điểm đánh dấu thì sao?
Hiện tại, kiểu của điểm đánh dấu danh sách không tương tác được vì có hai phương pháp khác nhau, một phương pháp do Gecko và Chromium (hiện tại) thực hiện và một phương pháp khác do WebKit thực hiện (trước đây được chia sẻ với Chromium).
Sau khi tính năng này có thể tương tác, mục tiêu của chúng tôi là giúp bạn kiểm soát tốt hơn cách tạo kiểu cho điểm đánh dấu.
Các bản minh hoạ khác
Cuối cùng, đây là một số bản minh hoạ khác để bạn tham khảo. Tất cả đều sử dụng ::details-content
.
Accordion UIKit
Bản minh hoạ
Đang ghi
Bản minh hoạ này được tạo sau Accordion UIKit. Mã này thực tế giống với trình đơn accordion (bật/tắt) trong Material UI đã được chia sẻ trước đó.
Tiện ích thông tin công bố mở một phần
Bản minh hoạ
Đang ghi
Bản minh hoạ này có một tiện ích thông tin công bố đã mở một phần, nội dung của tiện ích này đã hiển thị trên màn hình. Để đạt được điều này, content-visibility
luôn được đặt thành visible
. height
được tạo ảnh động bằng calc-size()
vì có liên quan đến một phép tính.
::details-content {
content-visibility: visible; /* Make it always visible */
transition: height 0.5s ease;
height: 150px;
overflow: clip;
}
[open]::details-content {
height: calc-size(auto, size + 0.5rem); /* calc-size because we need to add a length */
}
Để thuận tiện cho việc tạo kiểu, nội dung được gói trong một div trình bao bọc. Div trình bao bọc sẽ áp dụng các kiểu bố cục như padding
và ::details-content
giả lập sẽ được tạo hiệu ứng động.