對話方塊

對話方塊元素是用於在 HTML 中表示任何類型對話方塊的實用元素,請瞭解其運作方式。

強制回應對話方塊是網頁上一種特殊類型的彈出式視窗,會中斷使用者操作,讓他們專注於該視窗。彈出式對話方塊有幾種有效的用途,但在使用前,請先仔細考量。彈出式對話方塊會強制使用者專注於特定內容,並至少暫時忽略頁面上的其他內容。

對話方塊可以是模態 (只能與對話方塊中的內容互動),也可以是非模態 (仍可與對話方塊以外的內容互動)。模式對話方塊會顯示在其他網頁內容上方。頁面其餘部分為靜態,且預設會被半透明背景遮蔽。

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

以下是模式 <dialog> 的範例。使用「Open modal dialog」按鈕開啟對話方塊。開啟後,您可以透過三種方式關閉對話方塊:按下 Esc 鍵、提交表單 (表單中的按鈕已設定 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() 也會開啟對話方塊,但不會新增背景,也不會導致任何項目變成無效。Esc 鍵不會關閉非模式對話方塊。因此,您更應確保加入關閉非模式對話方塊的方法。這樣一來,如果關閉按鈕位於對話方塊外,焦點就會轉移至開啟對話方塊的元素,這可能不是最佳的使用者體驗。

雖然規格並未明文規定必須提供關閉對話方塊的按鈕,但建議您提供此按鈕。逃逸鍵會關閉互動對話方塊,但不會關閉非互動對話方塊。可接收焦點的顯示按鈕可改善無障礙和使用者體驗。

關閉對話方塊

您不需要使用 HTMLDialogElement.close() 方法關閉對話方塊。您完全不需要 JavaScript。如要關閉 <dialog> 而不使用 JavaScript,請在按鈕上設定 <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 屬性。

進行隨堂測驗

測驗您對對話方塊元素的瞭解程度。

您如何為對話方塊後方的區域設定樣式?

使用 ::backdrop 擬似元素。
使用 background 屬性。
使用 ::background 擬似元素。