跳到主要內容區
理解 Accessible Components: Disclosure & Accordion 篇
開發實作

理解 Accessible Components: Disclosure & Accordion 篇

一個無障礙的手風琴元件應具備哪些行為?能使用原生的 HTML 元素實作嗎?

更新日期:2026/05/21

發布日期:2024/09/22

作者:Kelly CHI

繼 Dialog 與 Tabs 元件後,本篇將繼續介紹 Disclosure 與 Accordion 這兩個元件。它們都具有將段落展開、收合的收納功能,讓使用者可以自行選擇要打開的段落進行瀏覽。對於鍵盤使用者而言,這樣的收納功能可以提升導覽效率,快速略過不感興趣的段落。

參考閱讀:理解 Accessible Components: Dialog 篇、理解 Accessible Components: Tabs 篇

Disclosure 是一個可展開與收合的元件,用來組織一個區塊的內容;而 Accordion 則是由數個可展開與收合的元件組成。我們可以將 Accordion 當成是多個 Disclosure 組合而成並加上更多語意的元件。使用者可以透過 Accordion 的展開與收合功能,一次僅瀏覽一個段落,避免資訊過載。

什麼是 Disclosure?

當我們想要讓使用者可以展開或收合一段內容時,一個常見的做法是使用 Disclosure 元件。

Disclosure 元件結構示意圖,標示三個組成部分:1. 用來指示內容開啟狀態的圖示(向下箭頭)、2. Disclosure 標題(範例為「This is a title」)、3. Disclosure 內容(展開後顯示的說明文字)。目前為展開狀態,內容說明 Disclosure 是一個可將內容收合或展開的元件,由一個按鈕與一個受按鈕控制顯示狀態的內容區塊組成。
Disclosure 元件通常由一個按鈕與在其後方的一些內容組成,圖片來源:A11y 新手村。

Disclosure 元件通常由一個按鈕與在其後方的一些內容組成,它有以下的特色:

  • 標題旁邊通常會有一個簡單的圖示,幫助在視覺上識別它是可互動的,並且當 Disclosure 的狀態改變時,它也會跟著改變以說明目前顯示狀態 。
  • Disclosure 的初始狀態可以為展開或收合,當元件為收合狀態時,任何使用者都無法看到這段內容,包括輔助科技的使用者。

範例

重要的鍵盤操作

當 Disclosure 獲得焦點時:

  • Enter 或 Space:切換 Disclosure 內容的顯示狀態。

重要的 ARIA 屬性

  • 控制展開和收合內容的元素具有 role=”button”。
  • 當內容展開時,角色為 “button” 的元素應將 aria-expanded 設為 “true”;當內容收合時,則應設為 “false”。
  • 角色為 “button” 的元素,使用 aria-controls 屬性,指向 Disclosure 的內容元素。

什麼是 Accordion?

手風琴 (Accordion) 是一組垂直堆疊起來的互動式標題 (Headings) 元件,每個手風琴段落都會包含一個標題、內容節錄或縮圖。這些互動式標題可讓使用者展開或收合相關的內容。當我們需要在單一頁面上顯示多個內容段落時,手風琴通常用來節省空間、減少捲動的需要。手風琴可以設定成同時間只能有一個展開的段落或是允許同時打開多個段落。

每個手風琴段落都包含兩個部分:

  • 手風琴標題 (Accordion Header):每個區段中可互動的部分,代表該內容段落的標籤或縮圖,同時也是控制顯示或隱藏內容的按鈕。
  • 手風琴面板 (Accordion Panel):與特定手風琴標題關聯的內容段落。

![Accordion 手風琴元件結構示意圖,標示兩個組成部分:1. 手風琴標題 Accordion Header,為每個區塊的可點擊標題列;2. 手風琴面板 Accordion Panel,為展開後顯示的內容區域。範例共有四個區塊,Section 2 Title 為展開狀態,其餘三個為收合狀態。]每個手風琴段落都包含兩個部分:手風琴標題以及手風琴面板,前者是每個區段中可互動的部分,後者則是與特定手風琴標題關聯的內容段落,圖片來源:A11y 新手村。

範例

重要的鍵盤操作

  • Enter 或 Space:當焦點在某個 Accordion Header 上時,切換 Accordion Panel 的顯示狀態。若該 Accordion 只允許單一段落為展開狀態,在另一個 Accordion Header 上按下 Enter 或 Space 時,會同時將原本已展開的段落收合。
  • 向下鍵 (非必要):如果焦點在 Accordion Header 上,將焦點移至下一個 Accordion Header。如果該 Header 已是 Accordion 中的最後一個,再次按下向下鍵並不會讓焦點回到第一個 Accordion Header。
  • 向上鍵(非必要): 如果焦點在 Accordion Header 上,將焦點移至上一個 Accordion Header。如果該 Header 已是 Accordion 中的第一個,再次按下向上鍵並不會讓焦點回到最後一個 Accordion Header。
  • Home 鍵 (非必要): 當焦點在 Accordion Header 上,將焦點移至第一個 Accordion Header。
  • End 鍵 (非必要): 當焦點在 Accordion Header 上,將焦點移至最後一個 Accordion Header。

重要的 ARIA 屬性

每個 Accordion Header 的文字需在 role=”button” 的元素中。
每個 Accordion Header 的 “button” 元素都在一個 Heading 元素中 (<h1>、<h2>…),該元素的標題層級須符合頁面的資訊架構。

<h3>
<button type="button" aria-expanded="true" aria-controls="sect1" id="accordion1id">
Personal Information
</span>
</button>
</h3>
  • 當對應的 Accordion Panel 為展開狀態時,標題 button 元素的 aria-expanded 應設定為 “true”。如果為收合狀態,aria-expanded 應設定為 “false”。
  • Accordion Header 應具有 aria-controls 屬性,並指向該 Header 所對應的 Panel ID。
  • 如果與 Accordion Header 對應的 Accordion Panel 為展開狀態,並且 Accordion 不允許收合時,標題 button 元素的 aria-disabled 設定為 true。(通常用於某個 Accordion 一定要有至少一個段落為展開狀態時。)

使用原生 HTML 來製作 Disclosure

<details> & <summary>

<details> 和 <summary>元素是 HTML 互動元素 其中的兩個標籤,它們共同組成了原生的 Disclosure 元件。 與前面提到的 ARIA Disclosure 元件相同,<details> 和 <summary> 允許展開和收合與 Disclosure 標題關聯的內容。

<details> 和 <summary> 元素的預期 markup 如下:

<details>
	<summary>
		<!-- 該 disclosure 的顯示標籤 -->
	</summary>
	<div>
		<!-- 用來調整樣式的 warpper (非必要) -->
		<!-- 可收合的內容在此 -->
	</div>
</details>

如果忘記在 <details> 中加入 <summary> 會怎麼樣?

如果沒有明確地加入 <summary> 元素,瀏覽器會自動將其加入 <details> 的第一個子元素。這個自動產生的 <summary> 中會包含「詳細資料」的本地化預設文字,例如若系統預設語言是中文,這個預設的標題會是「詳細資料」,這段文字也是 <summary> 元素的可訪問名稱。

範例:

使用原生 details & summary 的好處

![使用原生 details 和 summary 的好處,共兩點:能被 find-in-page 找到、details 和 summary 不需要 JS 來運作。。]使用原生的 details 跟 summary 元素有兩個好處,圖片來源:A11y 新手村。

  1. 能被 find-in-page 找到

在使用所有瀏覽器都有的「搜尋本頁內容 (find-in-page search)」功能時,對使用者 (包括輔助科技使用者) 隱藏的內容是無法被搜尋到的。

若以 ARIA 和 JavaScript 來開發 Disclosure 元件,我們會需要使用到 CSS 中 display:none 屬性來隱藏收合的內容。這會導致瀏覽器無法在隱藏的元素中找到符合搜尋結果的內容。

但是,如果使用 <details> 和 <summary> 元件來製作 Disclosure,瀏覽器的搜尋本頁內容是可以在收合的 <details> 元件中找到符合結果的內容的。(儘管目前只有 Chrome 與 Edge 支援此功能。)

  1. ARIA Disclosure 需要 JS 來運作,details & summary 不用

如同前面所提到的,若使用 ARIA 製作 Disclosure 元件,我們需要撰寫 Javascript 來使元件能夠正常展開和收合內容。然而,原生的 <details> 和 <summary> 元素則不需要任何 Javascript 就能運作。在某些無法使用 Javascript 的情境下,例如瀏覽器的「閱讀模式」,使用原生的 <details> 和 <summary> 能確保功能完整性。

這種優先以 HTML 完成功能的做法,是實踐 Progressive enhancement 的一個重要方式。Progressive enhancement 的目標在於讓更多人能夠使用網頁,不會因為某些限制條件(如無法載入 Javascript)而不能正常使用。

Disclosure & Accordion 無障礙體驗相關討論

  1. 須謹慎的使用否則使用者難以找到內容
    一個對 Disclosure 元件的常見批評是它讓資訊變得比較難被發現,雖然在 Chrome 和 Edge 中的搜尋本頁內容功能已經可以找到隱藏起來的內容,但是在其他瀏覽器中尚未完全支援,因此我們仍需要謹慎使用 Disclosure 元件來確保使用者可以接收與查找到重要的資訊。

  2. 目前還不能使用原生元素來製作 Accordion
    在現有的 HTML 元素中並沒有類似 <accordion> 的元素,但前面有提到,Accordion 其實是多個 Disclosure 的組合,那麼我們有辦法使用多個 <details> 跟 <summary> 來製作 Accordion 元件嗎?答案是,目前還不行。

在 MDN 文件中,有介紹到 details 元素的 name 屬性,這個屬性可以讓我們使用多個 details 元素,並在各 details 元素上使用 name 屬性將多個 details 給關聯起來。在這些關聯起來的 details 中,只允許同時有一個段落展開,若點擊另一個段落標題,會將原本展開的段落收合。

不過,這個屬性還沒有得到大部分主流瀏覽器的支援,且仍然有一些問題需要解決,因此仍不建議這樣使用。

其中的一個問題是 APG Pattern 中規範 Accordion Header 的部份需要有 heading 的語意。經過測試,目前若在 summary 元素外加上一層 h 元素,會讓 <details> 和 <summary> 無法正常運作。若在 details 外加上 h 元素又會同時讓標題與內容變成段落的標題。

此外,目前原生的行為只允許最多有一個展開的 Accordion Panel ,因此,如果希望能同時開啟多個 panel,是無法使用 details 加上 name 屬性來實作的。在鍵盤操作方面,原生也沒有支援鍵盤的上下鍵導航。

使用套件來製作 Disclosure & Accordion

如果我們單純想要製作單個可以展開或收合的內容,建議可以直接使用原生的 <details> 和 <summary> 元素來製作 Disclosure 元件,目前主流瀏覽器都有充分的支援。

至於 Accordion 元件,我們可以根據需求來選用適當的套件。

Radix UI

  • Accordion Header 使用 Heading 與 Button 元素。
  • 有支援上下鍵、Home 鍵、End 鍵操作,焦點會循環。
  • 可以透過參數設定是否可同時有多個段落展開,或只有一個。

https://www.radix-ui.com/primitives/docs/components/accordion

Chakra UI

  • Accordion Header 使用 Heading 與 Button 元素。
  • 有支援上下鍵操作,焦點會循環。
  • 可以透過參數設定是否可同時有多個段落展開,或只有一個。

https://v2.chakra-ui.com/docs/components/

Bootstrap

  • Accordion Header 使用 Heading 與 Button 元素。
  • 可以透過參數設定是否可同時有多個段落展開,或只有一個。

https://getbootstrap.com/docs/5.0/components/accordion/

參考資料

本文作者

本文作者

Kelly CHI

法文系畢業的前端工程師,致力於打造具有美感和良好用戶體驗的介面,同時也是個愛看冷門電影的骨灰級影迷。