搜尋隱藏的內容

網頁介面通常會隱藏內容,以改善使用者體驗、節省螢幕空間或提升網頁效能。display: none 或 visibility: hidden 等傳統方法可以隱藏內容,但也會讓螢幕閱讀器和「在網頁中尋找」等瀏覽器功能完全無法存取這些內容。

如要隱藏內容,但仍允許使用者搜尋,並透過網址片段和「捲動至文字片段」連結深層連結至該內容,可以使用 HTML <details> 元素或 hidden="until-found" 屬性。一般來說,我們建議使用 <details> 元素,因為實作和維護起來較為簡單,但在某些較複雜的情況下,<details> 並不夠用,必須使用 hidden="until-found"。

例如:

  • 想要完全掌控顯示/隱藏機制的樣式。
  • 顯示/隱藏內容的 UI 控制項位於 DOM 的其他部分。
  • 如果不想在內容顯示後隱藏。

導入方式

<details> 元素預設具有可搜尋及存取的文字,不需要特殊實作。建議盡可能使用 <details>,而非 hidden="until-found"。

如果需要改用 hidden="until-found",請按照下列操作說明進行:

  1. 套用屬性:直接將 hidden="until-found" HTML 屬性新增至包含應隱藏內容的元素。
  2. 同步處理 UI 狀態:如果介面有相關狀態取決於內容是否顯示 (例如更新 ARIA 屬性、切換開啟/關閉 CSS 類別,或旋轉摺疊式選單圖示):
    • 您必須為 beforematch 事件新增事件監聽器。
    • 直接在含有 hidden="until-found" 屬性的元素上註冊 beforematch 事件監聽器。由於事件會向上傳遞,您也可以使用事件委派,在父項元素 (例如分頁容器) 上註冊單一事件監聽器,一次管理多個隱藏區段。
    • 在事件監聽器中,執行邏輯來同步處理相關 UI 元素 (例如關閉其他開啟的分頁,或變更切換鈕的狀態)。

範例程式碼

目標:轉譯隱藏的容器,讓使用者在搜尋該部分中的字詞之前,無法看到內容。

使用 <details> 元素

<details>
  <summary>Click to expand</summary>
  <p>This content is visually hidden.</p>
</details>

互斥揭露聲明

處理互斥的內容區域 (例如互斥的手風琴式選單) 時,請使用原生 HTML <details> 元素和共用的 name 屬性。

<div class="accordion-group">
  <!-- The name attribute creates an exclusive disclosure group -->
  <details class="disclosure" name="my-accordion">
    <summary>Section 1</summary>
    <p>Section 1 content</p>
  </details>

  <details class="disclosure" name="my-accordion" open>
    <summary>Section 2</summary>
    <p>Section 2 content</p>
  </details>

  <details class="disclosure" name="my-accordion">
    <summary>Section 3</summary>
    <p>Section 3 content</p>
  </details>
</div>

使用 hidden="until-found" 屬性

<!-- The browser automatically removes hidden="until-found" upon a search match -->
<div class="hidden-container" hidden="until-found">
  <p>This content is visually hidden.</p>
</div>

自訂互斥揭露事項

處理外部按鈕控制的自訂互斥區域時,請確保只有相符的面板保持可見。在 beforematch 事件處理常式中,您必須同步處理相關的 ARIA 狀態,例如在控制按鈕上設定 aria-expanded="true"。

<div class="custom-accordion">
  <div class="controls">
    <button aria-expanded="true" aria-controls="panel-1" id="btn-1">Section 1</button>
    <button aria-expanded="false" aria-controls="panel-2" id="btn-2">Section 2</button>
  </div>

  <div id="panel-1" class="panel">
    <p>Section 1 content (visible)</p>
  </div>

  <div id="panel-2" class="panel" hidden="until-found">
    <p>Section 2 content (hidden)</p>
  </div>
</div>
const accordion = document.querySelector('.custom-accordion');

accordion.addEventListener('beforematch', (e) => {
  // Hide all panels and synchronize button states before the browser reveals the matched panel
  accordion.querySelectorAll('.panel').forEach((panel) => {
    if (panel !== e.target) {
      panel.hidden = 'until-found';
    }
  });
  accordion.querySelectorAll('button').forEach((btn) => {
    const controls = btn.getAttribute('aria-controls');
    btn.setAttribute('aria-expanded', controls === e.target.id ? 'true' : 'false');
  });
});

hidden="until-found"最佳做法

  • 務必將邊框、邊框間距和背景套用至巢狀子項包裝函式,而非直接套用至具有 hidden="until-found" 屬性的元素。這樣可以防止元素隱藏時,發生非預期的版面配置偏移或視覺殘留。
  • 請勿將 display: none、visibility: hidden 或任何相關聯的 display 或 visibility CSS 屬性直接套用至含有 hidden="until-found" 屬性的元素。這會破壞原生功能,並從搜尋索引中永久隱藏內容。
  • 請勿將 hidden="until-found" 用於機密資訊、內部資料權杖,或不應透過搜尋公開的不相關資料。
  • 請勿使用 hidden="until-found" 取代「僅限螢幕閱讀器」(.sr-only) 文字。

瀏覽器支援和備用策略

請勿因瀏覽器不支援而避免使用 hidden="until-found",因為其無障礙功能優勢遠大於實作備用方案的成本。

hidden="until-found"備用廣告

如果是摺疊式選單或「閱讀更多」等標準 UI 元素,請使用 JavaScript 偵測功能,並在不支援該功能時顯示所有內容。

if (!('onbeforematch' in HTMLElement.prototype)) {
  // Expand all hidden content for unsupported browsers
  document.querySelectorAll('[hidden="until-found"]').forEach((el) => {
    el.removeAttribute('hidden');
    // MANDATORY: also update any aria references to this element.
  });
}

如果是互斥的 UI 模式 (例如內容共用相同視覺區域的自訂專屬面板),備用方案應擷取所有內容,並在主要互動區域下方以線性方式顯示,同時使用網址錨定片段,讓使用者直接前往各個部分。