Đàn phong cầm độc quyền

Tạo một đàn phong cầm độc quyền gồm nhiều phần tử <details> có cùng name.

Đàn phong cầm

Mẫu giao diện người dùng phổ biến trên web là thành phần đàn phong cầm. Đây là thành phần bao gồm một số tiện ích thông tin công bố có thể mở rộng (hoặc thu gọn) một cách riêng lẻ để hiện (hoặc ẩn) nội dung.

Để triển khai mẫu này trên web, bạn sẽ kết hợp một vài phần tử <details> và thường nhóm lại một cách trực quan để cho biết các phần tử này thuộc về nhau.

Bản minh hoạ: Thu gọn với HTML và CSS.

Đàn phong cầm độc quyền

Hỗ trợ trình duyệt

  • Chrome: 120.
  • Cạnh: 120.
  • Firefox: 130.
  • Safari: 17.2.

Một biến thể của mẫu đàn phong cầm là đàn phong cầm độc quyền, trong đó chỉ có thể mở một trong các tiện ích thông tin công bố cùng một lúc.

Để thực hiện việc này trên web, giờ đây, bạn có thể thêm thuộc tính name vào các phần tử <details>. Khi bạn sử dụng thuộc tính này, nhiều phần tử <details> có cùng giá trị name sẽ tạo thành một nhóm ngữ nghĩa và chúng sẽ hoạt động như một nhóm ngữ nghĩa riêng. Khi bạn mở một trong các phần tử <details> của nhóm, phần tử bạn đã mở trước đó sẽ tự động đóng.

<details name="learn-css">
  <summary>Welcome to Learn CSS!</summary>
  <p>…</p>
</details>
<details name="learn-css">
  <summary>Box Model</summary>
  <p>…</p>
</details>
<details name="learn-css">
  <summary>Selectors</summary>
  <p>…</p>
</details>
Bản minh hoạ: Bản minh hoạ độc quyền dành cho HTML và CSS.

Một trang có thể có nhiều phong cầm độc quyền. Bất cứ khi nào bạn sử dụng một giá trị name mới trên phần tử <details>, một nhóm logic mới sẽ được tạo.

Bản minh hoạ: Nhiều đàn phong độc quyền với HTML và CSS.

Xin lưu ý rằng các phần tử <details> thuộc một đàn phong cầm độc quyền không nhất thiết phải là các phần tử đồng cấp. Chúng có thể nằm rải rác trên tài liệu. Đó là thuộc tính name giúp nhóm các hình ảnh đó, chứ không phải thứ tự DOM.

Polyfill (Người chơi đàn phong cầm độc quyền)

Với JavaScript sau đây, bạn có thể polyfill hành vi của đàn accordion độc quyền. Mã này dựa vào sự kiện toggle của phần tử <details>.

Khi một phần tử <details>name mở, mã này sẽ tìm các phần tử <details> mở khác có cùng giá trị cho thuộc tính name rồi đóng các phần tử đó lại.

document.querySelectorAll("details[name]").forEach(($details) => {
  $details.addEventListener("toggle", (e) => {
    const name = $details.getAttribute("name");

    if (e.newState == "open") {
      document
        .querySelectorAll(`details[name=${name}][open]`)
        .forEach(($openDetails) => {
          if (!($openDetails === $details)) {
            $openDetails.removeAttribute("open");
          }
        });
    }
  });
});

Một số phiên bản trình duyệt cũ không kích hoạt sự kiện toggle này. Trong các trình duyệt đó, mã polyfill sẽ không có tác dụng gì. Về tính năng nâng cao tăng dần, đây là hành vi được chấp nhận.