對話方塊

強制回應對話方塊是網頁上的特殊彈出式視窗類型,這類彈出式視窗會幹擾使用者註意本身。有些彈出對話方塊的有效用途,但必須在這麼做前多加考量。強制回應對話方塊會強制使用者專注於特定內容,至少暫時忽略頁面上的其餘部分。

對話方塊可以是強制回應 (只有對話方塊中的內容可以互動) 或非強制回應 (但對話方塊還是有可能與對話方塊外的內容互動)。強制回應對話方塊會顯示在其餘網頁內容的頂端。頁面的其餘部分為「插入」,且根據預設,會以半透明的背景遮蓋。

用來建立對話方塊的語意 HTML <dialog> 元素具有語意、鍵盤互動,以及 HTMLDialogElement 介面的所有屬性和方法。

以下是強制回應 <dialog> 的範例。開啟含有「開啟互動視窗」按鈕的對話方塊。開啟後,您可以透過三種方式關閉對話方塊:Escape 鍵、提交含有已設定 formmethod="dialog" 的按鈕 (或表單本身已設定 method="dialog") 的表單,以及 HTMLDialogElement.close() 方法的表單。

HTMLDialogElement 有三個主要方法,以及繼承自 HTMLElement 的所有方法。

dialog.show() /* opens the dialog */
dialog.showModal() /* opens the dialog as a modal */
dialog.close() /* closes the dialog */

由於這個 <dialog> 是透過 HTMLDialogElement.showModal() 方法開啟,因此是一個強制回應對話方塊。開啟強制回應對話方塊時,系統會停用並隱藏對話方塊本身以外的所有內容。如果將滑鼠遊標懸停在對話方塊外的 UI 上,就會發現所有元素的行為都視為 pointer-events: none; 已設定,即使是開啟對話方塊的按鈕也不會回應互動。

對話方塊開啟後,焦點會移至對話方塊中。焦點是在該對話方塊中按照鍵盤瀏覽順序排列的第一個元素。如果重複按下 tab 鍵,會留意,在強制回應對話方塊開啟時,只有對話方塊中的內容可以成為焦點。只要對話方塊開啟,所有強制回應對話方塊外的內容都會遭到叫用。

對話方塊關閉、互動視窗或未開啟時,焦點會返回開啟該對話方塊的元素。如果您是透過程式輔助方式開啟非根據使用者動作顯示的對話方塊,請重新考慮。如果必須,確保焦點會移回對話方塊開啟前的位置,特別是在使用者未與對話方塊互動的情況下關閉對話方塊。

只要透過一個全域 inert 屬性 (除了任何使用中的對話方塊外),就能停用元素及其所有子系。使用 showModal() 開啟強制回應對話方塊時,系統會免費執行插入或停用作業;屬性未明確設定。

如果背景遮蓋了對話方塊以外的內容,可以使用 ::backdrop 虛擬元素設定樣式。只有在使用 .showModal() 方法顯示 <dialog> 時,才會顯示背景幕。這個虛擬元素會符合所有背景幕,包括使用 FullScreen API 時顯示的背景,例如當以全螢幕模式觀看影片時,其長寬比與螢幕或螢幕不同。

非強制回應對話方塊

HTMLDialogElement.show() 也會開啟對話方塊,但不會新增背景幕或導致任何項目變為插邊。Escape 鍵不會關閉非互動對話方塊。因此,請務必納入關閉非互動對話方塊的方法。進行這項作業時,如果距離對話方塊太近,焦點就會前往開啟對話方塊的元素,因此可能無法提供最佳使用者體驗。

雖然規格未正式要求關閉對話方塊的按鈕,但請視需要考慮這麼做。逸出鍵會關閉互動視窗,但不會關閉非互動對話方塊。可接收焦點的可見按鈕可提升無障礙功能和使用者體驗。

關閉對話方塊

您不需要使用 HTMLDialogElement.close() 方法即可關閉對話方塊。完全不需要 JavaScript。如要在不使用 JavaScript 的情況下關閉 <dialog>,請在 <form> 上設定 method="dialog" 或在按鈕上設定 formmethod="dialog",加入含有對話方塊方法的表單。

使用者透過 dialog 方法提交時,系統會保留使用者輸入的資料狀態。如果有提交事件 (表單會通過限制驗證,除非已設定 novalidate),系統不會清除使用者資料,也不會提交使用者資料。不含 JavaScript 的關閉按鈕可寫成:

<dialog open>
  <form method="dialog">
    <button type="submit" autofocus>close</button>
  </form>
</dialog>

您可能已經注意到,在本範例中關閉 <button>autofocus 屬性。在 <dialog> 內設有 autofocus 屬性的元素,不會在載入網頁時聚焦 (除非網頁載入並顯示對話方塊)。不過,對話方塊開啟時就會聚焦。

根據預設,開啟對話方塊時,除非對話方塊中的其他元素已設定 autofocus 屬性,否則對話方塊中的第一個可聚焦元素都會成為焦點。在關閉按鈕上設定 autofocus 屬性,可確保這個屬性在開啟對話方塊時接收焦點。不過,在 <dialog> 中加入 autofocus 需要審慎考量。系統會略過自動聚焦元素前序列中的所有元素。我們會在焦點課程中進一步討論這個屬性。

HTMLDialogElement 介麵包含 returnValue 屬性。使用 method="dialog" 提交表單時,系統會將 returnValue 設為 name (如果有的話),也就是用於提交表單的「提交」按鈕。如果已編寫 <button type="submit" name="toasty">close</button>returnValue 會是 toasty

開啟對話方塊時,畫面上會顯示布林值 open 屬性,這表示對話方塊已啟用,可以與其互動。透過新增 open 屬性 (而不是透過 .show().showModal()) 開啟對話方塊時,對話方塊會以無回應方式執行。HTMLDialogElement.open 屬性會傳回 truefalse,這取決於對話方塊是否可用於互動 (而非互動模式)。

雖然我們建議使用 JavaScript 來開啟對話方塊,包括在載入網頁時使用 open 屬性,然後使用 .close() 移除該屬性,但這可確保即使 JavaScript 無法使用,系統仍可顯示對話方塊。

其他詳細資料

不要使用 tabindex

啟動來開啟對話方塊的元素,以及其中的關閉按鈕 (可能還有其他內容) 可以聚焦並進行互動。<dialog> 元素不具互動性,且不會聚焦。請勿將 tabindex 屬性新增至對話方塊本身。

ARIA 角色

隱含角色為 dialog。如果對話方塊是傳送需確認或其他使用者回應的重要訊息的確認視窗,請設定 role="alertdialog"。對話方塊也應具有可存取的名稱。如果顯示的文字可以提供無障礙元素名稱,請加入 aria-labelledby="idOfLabelingText"

CSS 預設值

請注意,瀏覽器提供 dialog 的預設樣式。Firefox、Chrome 和 Edge 會在使用者代理程式樣式表中設定 color: CanvasText; background-color: Canvas;,Safari 則設定 color: black; background-color: white;color 繼承自 dialog,而不是從 body:root 繼承而來,這可能是出乎意料的結果。不會沿用 background-color 屬性。

隨堂測驗

測驗您對對話方塊元素的相關知識。

對話方塊後方區域的樣式為何?

使用 ::background 虛擬元素。
請再試一次。
使用 ::backdrop 虛擬元素。
答對了!
使用 background 屬性。
請再試一次。