跳至主要內容

開發紀錄

頭像 dialog 的 Escape、backdrop 與焦點還原

從頭像放大互動,拆開原生 modal、背景點擊、關閉路徑和焦點還原的責任,並用實際瀏覽器操作確認圖片內容不會被誤當成關閉區域。

林予晴
發布
  • HTML
  • Dialog
  • 鍵盤操作
  • 互動驗證

把頭像放大到畫面中央,不是這個互動最難的部分。圖片顯示之後,鍵盤焦點要在哪裡、點圖片會不會誤關閉、按 Escape 後又回到哪裡,才決定了它是不是一個完整的操作。

本站關於頁使用原生 <dialog> 放大頭像。我這次把開啟與關閉路徑分開讀,也在本機瀏覽器實際操作。我要確認的不只是「圖片出現了」,而是讀者能從原本的控制進入,再回到原本的位置。

開啟 modal,不只是加上 open

頭像的放大入口是一個有名稱的原生按鈕。啟動後,腳本先把頁面上這張圖片的來源與 alt 放進 dialog,再呼叫 showModal()。

這和直接把一個區塊改成可見,責任不同。MDN 說明,透過 showModal() 開啟的 dialog 具有 modal 行為,外部內容會變成 inert;原生 modal 也提供預設的 Escape 關閉行為。[1]

因此,不能只看畫面有遮罩,就把它當成 modal。遮罩是呈現方式,鍵盤與焦點則需要實際的行為支持。

目前放大內容只有圖片和關閉按鈕。這次從頭像按鈕用 Enter 開啟後,焦點落在關閉控制上。MDN 對 showModal() 的焦點處理亦有說明,但如果之後加入更多可聚焦內容,仍要重新判斷合適的初始位置,不能把這次結果當成所有 dialog 都適用的排序。[1]

Escape 和關閉按鈕,要回到同一個結束流程

這個 dialog 沒有另寫一份攔截所有按鍵的 Escape handler。它保留原生 modal 的預設行為;畫面上的關閉按鈕則呼叫 close()。[1]

兩條路徑的輸入不同,結束後需要的狀態卻相同:dialog 不再開啟,焦點可以回到放大入口。

所以焦點還原放在 dialog 的 close 事件,而不是只放在關閉按鈕的 click 裡。如果還原只跟著按鈕走,按 Escape 或其他允許的關閉方式,就可能沒有經過同一段處理。

這次分別用 Escape 和關閉控制測試,兩者都讓 dialog 關閉,焦點也都回到原本的頭像放大按鈕。這比只測其中一條路徑更能確認目前的分工。

點背景關閉,先分清楚點到了誰

::backdrop 可以替 modal 後方加上暗色背景,但這份 CSS 不等於已經寫好了「點外面關閉」。本站的背景點擊處理在 dialog 的 click listener 裡,先判斷:

if (event.target === dialog) dialog.close()

這個判斷不能省略。圖片與關閉按鈕都在 dialog 裡,click 可能往外冒泡;如果只要 dialog 收到 click 就關閉,讀者點圖片本身也會把它關掉。

還有一個和版型有關的細節:目前 dialog 本體鋪滿視窗,圖片容器在中央。這篇所說的「點背景」,實際上是點到 dialog 本體的空白區,不是宣稱原生 ::backdrop 已經自動提供外部點擊關閉。事件目標與元素覆蓋範圍,必須一起看。

本機實測時,我分別點圖片中央和視窗角落的空白區。前者保留 dialog,後者關閉,且焦點回到頭像入口。兩個位置都要測,否則很容易只確認「能關掉」,卻漏掉「不應該關掉的地方」。

還原的是啟動位置,不是猜一個焦點目的地

開啟前,腳本記錄當時的 document.activeElement;關閉時,再把焦點送回記錄到的元素。

對目前這個互動來說,從頭像按鈕啟動,關閉後就回到同一顆按鈕。讀者不需要從頁面開頭重新找一次剛剛的位置。

這不等於所有複雜 dialog 都只需要相同做法。如果觸發元素在操作後被刪除、變成不可聚焦,或關閉後應該進入下一個工作步驟,就需要另外定義目的地。這些是後續設計情境,不是本站目前已經處理的功能。

目前能核對的是既有入口仍在的情況。我也測了一次 Tab 操作,焦點仍在這個 modal 內;這個觀察不代替所有焦點循環、螢幕閱讀器或手機輔助操作的驗收。

放大內容要和頁面上的圖片一致

目前只保留一張個人照,因此放大操作直接顯示頁面上的同一張圖片。

目前腳本從這張圖片複製 src 與 alt。這裡的 alt 不是另外維護一份放大視窗文案,而是沿用頁面上同一張圖片的描述。

這次開啟放大,確認 dialog 裡的圖片來源與 alt 都和頁面上的頭像一致。這只證明兩個呈現位置使用相同資料,不代表圖片內容描述本身已經通過所有可及性審查。

圖片用途、尺寸與載入失敗另有不同的責任,可以接著讀圖片的 alt、尺寸、載入與失敗狀態,為什麼要一起設計。這篇專注在圖片已經存在之後,如何進入和離開放大互動。

這次實際操作了哪些路徑

本輪使用 Windows 上的本機 Edge 無頭瀏覽器,透過瀏覽器輸入事件操作關於頁;沒有直接呼叫產品的開啟或關閉 handler 來代替點擊。

操作 這次確認的結果
頭像入口取得焦點後按 Enter dialog 開啟,焦點落在關閉按鈕
按 Escape dialog 關閉,焦點回到頭像入口
點圖片內容 dialog 保持開啟
在 modal 中按一次 Tab 焦點仍在 dialog 內
點關閉按鈕 dialog 關閉,焦點回到頭像入口
點 dialog 的背景空白區 dialog 關閉,焦點回到頭像入口
開啟原圖預覽 放大圖片的來源與 alt 和頁面上的頭像一致
離開後使用瀏覽器歷史返回 該次命中 BFCache,放大、Escape 與焦點還原仍可操作

這是一次本機功能觀察,不是主觀視覺驗收,也沒有涵蓋全部瀏覽器、連續多輪歷史返回或輔助科技。無 JavaScript 時仍有原始頭像與介紹內容,但這份放大行為需要腳本,不能把靜態內容可讀說成無腳本互動也已成立。

我會把這種小互動的完成條件寫到「關閉後回到哪裡」,而不是停在「點下去看得到」。圖片出現只是操作的中段。

Sources

[1] https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/dialog