Menu

Thẻ details và summary HTML: phần nội dung thu gọn

Phần tử <details> và <summary> tạo một phần nội dung thu gọn được mà không cần JavaScript: summary luôn hiển thị, nhấp vào nó sẽ hiện hoặc ẩn phần còn lại. Tìm hiểu cách viết, thuộc tính open và name, accordion, định dạng mũi tên và sự kiện toggle.

Trang này có trình soạn thảo chạy trực tiếp. Sửa, chạy và xem đầu ra ngay lập tức.

Nội dung thu gọn với details và summary

Bọc nội dung trong <details> và đặt <summary> lên đầu. Summary luôn hiển thị; mọi thứ khác bị ẩn cho tới khi người đọc nhấp vào nó:

Nhấp vào câu hỏi để mở, nhấp lần nữa để đóng. Trình duyệt thêm dấu tam giác, cho summary nhận focus, bật tắt nó bằng Enter hoặc Space, và báo cho trình đọc màn hình biết nó đang mở hay đóng. Không có chút JavaScript nào.

Nếu bạn bỏ <summary>, trình duyệt sẽ hiện một nhãn mặc định ("Details" trong tiếng Anh).

Mở sẵn

Thuộc tính boolean open hiển thị nội dung ngay từ đầu. Trình duyệt thêm và xóa open khi người đọc bật tắt, nên đây cũng là chỗ để định dạng:

Khung đang mở có viền xanh nhờ details[open]. Mở "Returns" thì nó cũng chuyển xanh; cả hai có thể mở cùng lúc.

Accordion: mỗi lần chỉ mở một mục

Cho nhiều phần tử <details> cùng một name và chúng trở thành một nhóm loại trừ: mở một mục sẽ đóng các mục khác. Việc này trước đây cần JavaScript, giờ chỉ cần thuộc tính trên các bản Chrome, Edge, Firefox và Safari hiện tại:

Mở câu hỏi thứ hai thì câu đầu đóng lại. Xóa các thuộc tính name thì chúng lại mở độc lập với nhau. Accordion loại trừ ẩn đi nội dung mà người đọc có thể muốn so sánh, nên hãy dùng nó khi các mục là những phương án thay thế nhau, và dùng <details> thường khi người đọc có thể muốn mở nhiều mục.

Định dạng dấu mũi tên

Dấu tam giác là một list marker trên summary. list-style: none xóa nó (quy tắc ::-webkit-details-marker dành cho Safari), và một pseudo-element có thể vẽ dấu hiệu của riêng bạn:

Dấu cộng xoay 45 độ thành dấu nhân khi mục được mở. Hãy giữ kiểu focus nhìn thấy được như viền :focus-visible ở đây: khi đã bỏ dấu mặc định, vòng focus là thứ người dùng bàn phím dựa vào.

Sự kiện toggle và thuộc tính open

JavaScript có thể đọc và đặt details.open, và sự kiện toggle được phát sau mỗi lần thay đổi, dù do cú nhấp, phím hay script gây ra:

"Expand all" đặt open cho cả hai, và nhật ký hiển thị sự kiện toggle gần nhất. Sự kiện này không nổi bọt (bubble), nên hãy lắng nghe trên từng phần tử <details> thay vì trên phần tử cha.

Nên đặt gì trong summary

Summary chứa chữ, phần tử inline, hoặc một tiêu đề khi tên của phần đó thuộc về dàn ý của trang:

<details>
  <summary><h3>Refund policy</h3></summary>
  <p>...</p>
</details>

Tránh đặt link, nút và trường form bên trong <summary>: summary vốn đã là một nút điều khiển, nên một nút điều khiển bên trong nó dễ bị bỏ sót hoặc bấm nhầm, và trình đọc màn hình đọc các nút lồng nhau rất kém. Hãy đặt nội dung tương tác trong phần thân của <details>.

Lỗi thường gặp

  • Tự làm nút ẩn hiện bằng <div> và JavaScript. <details> đã xử lý sẵn cú nhấp, phím và trạng thái cho trình đọc màn hình. Khi thật sự cần nút ẩn hiện tùy chỉnh, hãy dùng nút với aria-expanded.
  • Đặt <summary> ở vị trí khác ngoài vị trí đầu. Nó phải là phần tử con đầu tiên của <details>.
  • Ẩn dấu mũi tên mà không có gì thay thế. Hãy cho người đọc một dấu hiệu rằng summary mở ra được, như dấu cộng ở trên.
  • Dùng display để ẩn nội dung. Hãy bật tắt open; CSS ép nội dung hiện hay ẩn sẽ xung đột với trạng thái của trình duyệt.
  • Nhóm loại trừ cho nội dung người đọc cần so sánh. Chỉ dùng name khi việc mỗi lần mở một mục là hợp lý.

Câu hỏi thường gặp

details và summary có tác dụng gì trong HTML?

<details> tạo một tiện ích ẩn hiện: một phần nội dung có thể mở và đóng. Phần tử con đầu tiên của nó, <summary>, là nhãn luôn hiển thị; nhấp vào nó (hoặc nhấn Enter hay Space khi nó có focus) sẽ hiện hoặc ẩn mọi thứ còn lại bên trong <details>.

Làm sao để phần tử details mở sẵn?

Thêm thuộc tính boolean open: <details open>. Trình duyệt tự thêm và xóa thuộc tính này khi người dùng bật tắt, nên CSS có thể định dạng details[open].

Làm sao tạo accordion chỉ mở một mục mỗi lần?

Cho mọi <details> trong nhóm cùng một thuộc tính name, ví dụ name="faq". Mở một mục sẽ đóng các mục khác trong nhóm đó, không cần JavaScript.

Làm sao xóa hoặc đổi mũi tên của details summary?

Đặt list-style: none cho summary và thêm summary::-webkit-details-marker { display: none; } cho Safari. Sau đó tự vẽ dấu hiệu của bạn, ví dụ bằng summary::after, và thay đổi nó bằng details[open] summary::after.

Có biết được khi nào phần tử details mở không?

Có. Lắng nghe sự kiện toggle trên phần tử <details> và đọc thuộc tính open của nó. Đặt details.open = true trong JavaScript sẽ mở nó.

Hình minh họa các ngôn ngữ lập trình của Coddy

Học lập trình cùng Coddy

Bắt đầu