HTML 原生 dialog 完整教學:不用套件也能做出專業 Modal
快速解答
用 dialog 標籤包住內容,搭配 JavaScript 的 showModal() 開啟、close() 關閉。不需要任何套件,瀏覽器全面支援,還內建無障礙功能和 ::backdrop 遮罩。
還在自己刻 Modal?瀏覽器早就幫你做好了
以前要做一個 Modal,需要:
- 自己寫一層
.overlaydiv 遮住背景 - 用 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 開關示範
::backdrop:自訂背景遮罩
showModal() 開啟時,瀏覽器會自動產生一個 ::backdrop 偽元素蓋在 Modal 後方。你可以直接用 CSS 改它的外觀:
dialog::backdrop {
background: rgba(0, 0, 50, 0.6);
backdrop-filter: blur(8px);
}以前要做毛玻璃背景遮罩,需要自己疊很多層 div;現在一行 CSS 就搞定。
自訂 ::backdrop 毛玻璃效果
表單整合: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
注意開啟時的滑入動畫
常見問題
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 留給需要向下相容的舊專案就好。