HTML <dialog> 對話框標籤

HTML <dialog> 標籤是用來在網頁中建立「對話框」(dialog boxes) 或「彈窗」(popup windows) 的原生 HTML 元素。在 HTML5 之前,我們通常需要使用大量的 JavaScriptCSS (例如設定 z-indexdisplay: none) 來手動模擬對話框,現在有了 <dialog> 標籤,我們可以更輕鬆地實作功能完善且符合無障礙 (A11Y) 標準的彈窗。

<dialog> 的基本用法

要建立一個對話框,只需要將內容包在 <dialog> 標籤中即可:

<dialog id="myDialog">
  <p>這是一個簡單的對話框內容!</p>
  <button id="closeBtn">關閉</button>
</dialog>

<button id="openBtn">開啟對話框</button>
預設情況下,<dialog> 是隱藏的,除非加上了 open 屬性或是透過 JavaScript 控制。

透過 JavaScript 控制對話框

<dialog> 標籤提供了一些原生的方法來控制顯示與關閉:

  • .show(): 開啟一個「非強制性」(non-modal) 的對話框。使用者仍然可以與背景的其他元素互動。
  • .showModal(): 開啟一個「強制性」(modal) 的對話框。這是最常用的方式,它會讓背景變暗(遮罩效果),且使用者無法操作背景元素,直到對話框關閉為止。
  • .close(): 關閉對話框。

程式碼範例

const dialog = document.getElementById('myDialog');
const openBtn = document.getElementById('openBtn');
const closeBtn = document.getElementById('closeBtn');

// 開啟強制性對話框
openBtn.addEventListener('click', () => {
  dialog.showModal();
});

// 關閉對話框
closeBtn.addEventListener('click', () => {
  dialog.close();
});

效果如下:

這是一個簡單的對話框內容!

<dialog> 的優點

使用原生的 <dialog> 標籤有以下幾個顯著優點:

  1. 自動處理層次 (Top Layer):使用 showModal() 時,對話框會自動出現在最上層,你不再需要處理煩人的 z-index 問題。
  2. 鍵盤支援:開啟 Modal 後,瀏覽器會自動捕捉 Tab 鍵的焦點範圍在對話框內,且按下 Esc 鍵會自動關閉對話框(除非被阻止)。
  3. 無障礙支援 (Accessibility):螢幕閱讀器可以正確識別這是一個對話框視窗。
  4. 原生遮罩樣式:你可以使用 CSS 的 ::backdrop 偽元素輕鬆自訂背景遮罩的顏色或模糊效果。

如何自訂遮罩樣式 (::backdrop)

當你使用 showModal() 開啟對話框時,瀏覽器會生成一個背景遮罩。我們可以用 ::backdrop 來美化它:

/* 自訂對話框背景 */
dialog::backdrop {
  background-color: rgba(0, 0, 0, 0.5); /* 半透明黑色 */
  backdrop-filter: blur(5px); /* 毛玻璃模糊效果 */
}

/* 自訂對話框本體樣式 */
dialog {
  border: none;
  border-radius: 8px;
  padding: 20px;
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}

表單與 <dialog> 的結合

如果你在對話框內放了一個表單,可以將 <form>method 屬性設定為 dialog。這樣一來,當使用者按下送出按鈕時,對話框會自動關閉,並將按鈕的 value 作為結果傳回。

<dialog id="favDialog">
  <form method="dialog">
    <p>你最喜歡的程式語言?</p>
    <select name="lang">
      <option value="js">JavaScript</option>
      <option value="python">Python</option>
    </select>
    <div>
      <button value="cancel">取消</button>
      <button value="confirm">確認</button>
    </div>
  </form>
</dialog>

<button onclick="document.getElementById('favDialog').showModal()">這是一個選擇題</button>

效果如下:

你最喜歡的程式語言?

當對話框關閉時,你可以透過 dialog.returnValue 取得按下按鈕的 value

瀏覽器支援度

截止至 2024 年,所有主流現代瀏覽器(Chrome, Firefox, Safari, Edge)皆已完整支援 <dialog> 標籤。如果你需要支援非常老舊的瀏覽器,可以考慮使用 Polyfill 或是傳統的 Modal 實作方式。