# 前提:當使用 modal 元件卻自己手刻按鈕來執行關閉 modal 時,觸發"焦點"警告訊息 首先是警告訊息碼: ``` Blocked aria-hidden on an element because its descendant retained focus. The focus must not be hidden from assistive technology users. Avoid using aria-hidden on a focused element or its ancestor. Consider using the inert attribute instead, which will also prevent focus. For more details, see the aria-hiddensection of the WAI-ARIA specification at https://w3c.github.io/aria/#aria-hidden. Element with focus: <div.modal fade#exampleModal> Ancestor with aria-hidden: <div.modal fade#exampleModal> <div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" style="display: block;" aria-hidden="true">…</div> 解釋: 1. 你看到這個警告的原因是:目前被聚焦(focus)的元素(在這裡是 modal)位於一個設定了 aria-hidden="true" 的元素之中。 2. 當一個元素被標記為 aria-hidden="true" 時,輔助技術(例如螢幕閱讀器)會忽略這個元素 以及它所有的子元素。 3. 但此時焦點仍然停留在這個被隱藏的區域中,就會造成無障礙(Accessibility)衝突。 ``` **QA: 為什麼會觸發此警告訊息碼呢?** 🔍 當關閉按鈕是自己手刻並在 `<label>` 自行加入 data-bs-dismiss="modal" 屬性後 ; 導致**焦點 (focus) 與 aria-hidden 屬性之間的時序問題**造成的。 ``` html. <div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" style="display: block;" aria-hidden="true"> ... <div class="modal-footer modal-footer-padding"> <label for="update-password" class="btn border printPadding rounded-16 m-0 text-bg-dark" data-bs-dismiss="modal" @click.prevent="updatePwd($event)"> 更新密碼 <span class="material-icons-outlined align-bottom ms-1"> chevron_right </span> </label> <input type="text" id="update-password" name="update-password" class="d-none"> </div> </div> ``` --- **QA: 那如果將 aria-hidden 這個屬性直接移除可行嗎??** 👉 在 Web3 或現代 Web 規範中,即使是 Web3 應用(或任何前端框架:例如使用 React、Next.js、dApp 前端等),仍然是建立在 HTML5 + WAI-ARIA 規範之上,所以仍然會遵守 WAI-ARIA 標準。但`aria-hidden="true"`在特定情境下並不是「一定要有」的屬性,它是一個可選的輔助屬性。 -- **QA: 那 aria-hidden="true" 到底該在哪裡用、何時該避免用??** 🧭 1. 首先來看 `aria-hidden="true"` 的核心用途 **目的:** * 讓螢幕閱讀器(Screen Reader)忽略某個元素和它的所有子元素 ; 它不會影響畫面顯示,只影響「輔助技術」的可見性。 **換句話說:** * 視覺上 → 元素仍然存在。 * 螢幕閱讀器 → 當作不存在。 🎯 2. 實際使用場景分類 | 使用情境 | 是否應使用 `aria-hidden="true"` | 原因說明 | | ------------------------------------- | -------------------------- | ----------------------------------------------------------------- | | **裝飾性元素**(例如純 icon、SVG、背景圖案) | ✅ 是 | 讓螢幕閱讀器略過這些沒有語意的圖像。 | | **用來輔助顯示但非資訊重點的元素**(例如重複顯示的標題、陰影層) | ✅ 是 | 避免螢幕閱讀器重複讀出內容。 | | **顯示動畫、載入中轉圈圈 (spinner)** | ✅ 是 | 通常不需要被朗讀。 | | **顯示狀態切換時隱藏某區塊(非使用 `display:none`)** | ✅ 可用 | 例如透過 `visibility: hidden` 隱藏時,補上 `aria-hidden="true"` 讓螢幕閱讀器同步忽略。 | | **背景被 modal 蓋住時** | ✅ 是 | 當 modal 開啟時,把背景主內容標記為 `aria-hidden="true"`,避免螢幕閱讀器「穿透」去讀背景。 | | **Modal、Dialog、Alert 本身** | ❌ 否 | 它應該可被螢幕閱讀器讀取與操作。 | | **互動元素(按鈕、輸入框、選單)** | ❌ 否 | 否則會讓使用者無法透過輔助技術使用該元件。 | | **被 `display:none` 或 `hidden` 隱藏的元素** | ❌ 否 | 因為它們已經自動被螢幕閱讀器忽略,不需重複設定。 | -- 🧩 3. 典型範例 ``` ✅ 正確使用:純裝飾圖示 <button> <span class="icon" aria-hidden="true">⭐</span> 收藏 </button> ``` * 螢幕閱讀器只會讀出「收藏」,不會念出「星星」這個符號。 -- ``` ✅ 正確使用:開啟 modal 時隱藏背景 <main id="page-content" aria-hidden="true"> <!-- 背景內容 --> </main> <div role="dialog" aria-modal="true"> <!-- modal 內容 --> </div> ``` * 這樣可以讓螢幕閱讀器專注在對話框(modal)內,不會「跳出去」讀取背景。 -- ``` ❌ 錯誤使用:把互動內容藏起來 <div aria-hidden="true"> <button>提交</button> </div> ``` * 這會讓輔助技術無法找到「提交」按鈕,也無法操作它。 --- **QA: 那能怎麼解決 "焦點出錯" 這樣的警告訊息呢??** * 首先我們先來看 **"焦點管理的流程"** 如下: ``` [初始狀態] Modal 元素: - aria-hidden="true" - display: none - 無焦點 使用者操作: 點擊「開啟 modal 按鈕」 (Bootstrap 提供或自己手刻) │ ▼ [Bootstrap 開啟 modal] - 移除 aria-hidden - 加上 .show - 聚焦到 modal 的第一個可聚焦元素 - modal 內容被螢幕閱讀器讀取 - 焦點現在在 modal 內 │ ▼ [使用者操作] 點擊「手刻關閉按鈕」 (data-bs-dismiss="modal" + updatePwd) │ ▼ [你的程式執行] - document.activeElement.blur() → 將焦點移出 modal 內的元素,避免焦點留在被隱藏元素上 - 執行業務邏輯,例如更新密碼 │ ▼ [Bootstrap JS 處理關閉] - 移除 .show - 加回 aria-hidden="true" - 將焦點移回觸發 modal 的按鈕 (或上一次聚焦元素) - modal 完全隱藏,焦點安全轉移 - 不會觸發「Blocked aria-hidden」警告 │ ▼ [結束] - modal 隱藏 - 焦點安全在頁面上 - 輔助技術(螢幕閱讀器)正常讀取 ``` #### 按照上述的流程圖來看,可以知道 Bootstrap 的 modal 在 初始狀態會設定: `<div class="modal fade" id="exampleModal" tabindex="-1" aria-hidden="true">` #### 所以一開始 modal 是隱藏的,螢幕閱讀器不會讀它 * 當開啟 modal 時,Bootstrap JS 會自動: 1. 移除 aria-hidden="true" 2. 加上 .show 3. 聚焦到 modal * 關閉 modal 時,Bootstrap JS 會自動: 1. 移除 .show 2. 加回 aria-hidden="true" 3. 將焦點移回觸發 modal 的按鈕 所以依照上述來看 Bootstrap JS 已經管理了 aria-hidden,不需要手動刪掉或加上。 -- **❌ 那為什麼你現在會跳警告??** **你自己手刻的 `<label>` 當作關閉按鈕,按下時:** * Bootstrap 會觸發 modal 關閉 * 但是你的程式裡有 焦點還在 modal 元素內 -- #### 💡 所以我們只需保留 Bootstrap 預設 `aria-hidden="true"`,並透過 JS 來消除 "焦點" 的警告訊息即可 ``` js. updatePwd(e){ // 先讓焦點移到文件主體,避免焦點留在 modal 裡 document.activeElement.blur(); } ``` ✅原理: * 焦點移出 modal 內的元素 * Bootstrap 自己會在動畫結束時自動加回 aria-hidden="true" ✅效果: * 不會有警告 * modal 正常開關 * 輔助技術可以正常讀取焦點轉移
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up