技術

HTML 原生 dialog 完整教學:不用套件也能做出專業 Modal

#HTML#dialog#modal#前端教學#無障礙設計
HTML dialog 元素完整教學示意圖

快速解答

用 dialog 標籤包住內容,搭配 JavaScript 的 showModal() 開啟、close() 關閉。不需要任何套件,瀏覽器全面支援,還內建無障礙功能和 ::backdrop 遮罩。

還在自己刻 Modal?瀏覽器早就幫你做好了

以前要做一個 Modal,需要:

  • 自己寫一層 .overlay div 遮住背景
  • 用 JavaScript 切換 display: none / block
  • 手動鎖定背景捲動
  • 自己監聽 Esc 鍵關閉
  • 還要處理無障礙(focus trap、aria 屬性)

現在呢?HTML 原生 <dialog> 幫你全部搞定,一個標籤解決所有問題。

瀏覽器支援率已超過 96%,Chrome、Firefox、Safari、Edge 全面支援,可以放心用在正式專案。

基本語法:開啟與關閉

<dialog> 的核心很簡單,只要記住兩個 JavaScript 方法:

<dialog id="my-modal">
  <p>這是 Modal 的內容</p>
  <button id="close-btn">關閉</button>
</dialog>

<button id="open-btn">開啟 Modal</button>
const modal = document.getElementById('my-modal');

document.getElementById('open-btn').addEventListener('click', () => {
  modal.showModal(); // 開啟 Modal(帶背景遮罩)
});

document.getElementById('close-btn').addEventListener('click', () => {
  modal.close(); // 關閉 Modal
});

showModal() vs show() 的差異

方法效果
showModal()全屏 Modal,產生 ::backdrop 遮罩,自動鎖定焦點,Esc 鍵可關閉
show()非阻斷彈窗,無遮罩,不鎖定焦點

一般做 Modal 用 showModal(),工具提示或浮動面板用 show()

基本 Modal 開關示範

這是一個原生 Modal

完全不需要任何套件。背景遮罩、Esc 關閉、焦點鎖定,瀏覽器全部幫你處理好了。

::backdrop:自訂背景遮罩

showModal() 開啟時,瀏覽器會自動產生一個 ::backdrop 偽元素蓋在 Modal 後方。你可以直接用 CSS 改它的外觀:

dialog::backdrop {
  background: rgba(0, 0, 50, 0.6);
  backdrop-filter: blur(8px);
}

以前要做毛玻璃背景遮罩,需要自己疊很多層 div;現在一行 CSS 就搞定

自訂 ::backdrop 毛玻璃效果

注意背後的效果

背景是用 ::backdrop 搭配 backdrop-filter: blur() 做的,不需要額外的 div,一個偽元素全包。

表單整合:method='dialog'

這是 <dialog> 最強的隱藏功能之一:把 <form>method 設為 "dialog",送出表單時會自動關閉 dialog 並記錄按下的按鈕值,確認/取消邏輯完全不需要自己寫。

<dialog id="confirm-modal">
  <p>確定要刪除這筆資料嗎?</p>
  <form method="dialog">
    <button value="cancel">取消</button>
    <button value="confirm">確定刪除</button>
  </form>
</dialog>
modal.addEventListener('close', () => {
  // returnValue 是被點擊按鈕的 value
  if (modal.returnValue === 'confirm') {
    // 執行刪除邏輯
  }
});

confirm 確認對話框

選擇確認或取消後看結果

確定要刪除這筆資料嗎?此操作無法復原。

進場動畫:@starting-style

<dialog> 預設沒有開啟動畫,但搭配 CSS 的 @starting-style,可以做出純 CSS 的進場動畫,不需要 JavaScript 切換 class。

dialog[open] {
  opacity: 1;
  transform: translateY(0);
  transition: opacity 0.3s ease, transform 0.3s ease;
}

@starting-style {
  dialog[open] {
    opacity: 0;
    transform: translateY(-16px);
  }
}

@starting-style 定義的是元素剛出現時的初始值,transition 接著把它帶到 dialog[open] 的樣式,產生平滑進場。這個方法不需要任何 JavaScript,純 CSS 搞定。

支援度:Chrome 117+、Firefox 129+、Safari 17.5+,涵蓋超過 90% 的使用者。

帶進場動畫的完整 Modal

注意開啟時的滑入動畫

設定已儲存

你的變更已成功套用

這個 Modal 使用 @starting-style 製作純 CSS 進場動畫,毛玻璃背景用 ::backdrop,整體不依賴任何 JavaScript 動畫套件。

常見問題

Q:點擊背景遮罩可以關閉嗎?

原生 <dialog> 不支援點擊背景關閉,需要自己加:

modal.addEventListener('click', (e) => {
  if (e.target === modal) modal.close();
});

Q:可以防止 Esc 鍵關閉嗎?

modal.addEventListener('cancel', (e) => {
  e.preventDefault();
});

Q:跟 Bootstrap modal 比有什麼缺點?

  • 關閉動畫需要額外處理(@starting-style 目前只支援進場)
  • 沒有內建的「點擊背景關閉」行為
  • 舊專案遷移有一定成本

不過新專案的話,原生 <dialog> 無需套件、天生無障礙、效能更好,完全值得優先選用。

總結:值得換掉舊寫法嗎?

如果你還在用這些方式做 Modal:

  • Bootstrap modal
  • 自己用 div 疊出來的 overlay
  • jQuery UI dialog

是時候換了。<dialog> 的優勢很明確:

  • 無障礙免費送:自動管理 focus trap、aria 屬性
  • Esc 鍵內建:不需要自己監聽
  • 背景鎖定showModal() 自動阻止背景捲動
  • ::backdrop:遮罩樣式一行 CSS
  • 零依賴:不需要任何套件

對新專案來說,<dialog> 應該是預設選擇。Bootstrap modal 留給需要向下相容的舊專案就好。

你可能還會喜歡

技術

HTML Popover API 完整教學:不用 JavaScript 也能做彈跳框

#HTML#popover#前端教學#無障礙設計
技術

下拉選單怎麼做?三層式選單製作完整指南

#下拉選單#CSS#導航設計#前端技術
資源

網頁設計師要用什麼Chrome擴充?2025年30款必備推薦

#Chrome擴充功能#網頁設計工具#設計師工具#工作效率
指南

網站製作前要準備什麼?7步驟資料準備指南

#網頁設計#專案規劃#網站建置#設計流程