網頁介面通常會隱藏內容,以改善使用者體驗、節省螢幕空間或提升網頁效能。display: none 或 visibility: hidden 等傳統方法可以隱藏內容,但也會讓螢幕閱讀器和「在網頁中尋找」等瀏覽器功能完全無法存取這些內容。
如要隱藏內容,但仍允許使用者搜尋,並透過網址片段和「捲動至文字片段」連結深層連結至該內容,可以使用 HTML <details> 元素或 hidden="until-found" 屬性。一般來說,我們建議使用 <details> 元素,因為實作和維護起來較為簡單,但在某些較複雜的情況下,<details> 並不夠用,必須使用 hidden="until-found"。
例如:
- 想要完全掌控顯示/隱藏機制的樣式。
- 顯示/隱藏內容的 UI 控制項位於 DOM 的其他部分。
- 如果不想在內容顯示後隱藏。
導入方式
<details> 元素預設具有可搜尋及存取的文字,不需要特殊實作。建議盡可能使用 <details>,而非 hidden="until-found"。
如果需要改用 hidden="until-found",請按照下列操作說明進行:
- 套用屬性:直接將
hidden="until-found"HTML 屬性新增至包含應隱藏內容的元素。 - 同步處理 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或visibilityCSS 屬性直接套用至含有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 模式 (例如內容共用相同視覺區域的自訂專屬面板),備用方案應擷取所有內容,並在主要互動區域下方以線性方式顯示,同時使用網址錨定片段,讓使用者直接前往各個部分。