HTML Dialog

關於 Modal 與 Dialog

在今日的網站開發上,使用彈窗式的介面來呈現資訊只要是接觸過網站開發的人應該都不陌生,而在過去我們對於彈窗式介面的實現方式,通常是透過 JavaScript 控制 class 來達成,但這樣的方式在維護上會有一些問題,例如:對於 Modal 或 Dialog 的顯示位置我們都需要另外寫一份 CSS 去設計,需要使用 .open 之類的 CSS class 來控制開關,或者需要額外的元素實現 Modal 的背景,而這樣的實現成本比較高,而且也不易維護。而在 HTML5 中,我們可以透過 dialog 標籤來實現彈窗式介面,這樣的實現方式不僅簡單,而且也不需要透過 JS 來控制 CSS Class,接下來就讓我們來看看如何使用 dialog element。

Modal 是一種介面的設計模式,而 Dialog 則是一種介面的元素,Modal 通常會使用 Dialog 來實現,但 Dialog 並不一定是 Modal,例如:我們可以透過 Dialog 來實現一個提示訊息的介面,而這個介面並不是 Modal,因為它並不會阻止使用者對其他元素進行操作,而 Modal 則是會阻止使用者對其他元素進行操作,直到 Modal 關閉為止。

兩者最大的差異在於:Modal 會阻止使用者對其他元素進行操作,而 Dialog 則不會。對我來說,Modal 是一個完全阻隔的彈窗內容並且顯示在畫面上的中央,而 Dialog 比較像是一個提示訊息的介面。

使用 Dialog

要使用 Dialog 很簡單,只需要在 HTML 中加入 <dialog> 元素即可,例如:

<dialog open>
  <p>Greetings, one and all!</p>
  <form method="dialog">
    <button>OK</button>
    <button (click)="closeDialog()">Cancel</button>
  </form>
</dialog>

open attribute 會讓 Dialog 在載入時就顯示出來,而 form 中的 method 屬性則是用來指定 Dialog 的行為,預設值為 dialog,也就是當使用者點擊 form 中的 button 時,Dialog 會關閉,如果我們將 method 屬性設定為 get,則會將 form 中的資料以 GET 的方式送出,而如果設定為 post,則會以 POST 的方式送出,這樣的設定方式和一般的 form 是一樣的。

Dialog 的 JS 操作方法

要在 JavaScript 操作 Dialog 或 Modal,我們可以透過 show() 來顯示 Dialog,而 showModal() 則是以 Modal 方式呈現,兩者皆可使用 close() 方法來關閉 Modal 與 Dialog:

const dialog = document.querySelector('dialog');
function openDialog() {
  dialog.showModal(); // for modal
  // dialog.show(); // for dialog
}
function closeDialog() {
  dialog.close();
}

Dialog 的 CSS 操作方法

關於 Style 的部分,Dialog 有一些預設的樣式,例如:showModal() 會自動置中,並且有陰影效果,這些預設的樣式讓我們只需要專注在介面呈現的風格,我們也可以透過 CSS 來進行修改,假設要調整 Modal 的陰影效果我們可以使用 ::backdrop 調整:

dialog::backdrop {
  background-color: rgba(0, 0, 0, 0.5);
}

Dialog 的事件

Dialog 也有一些事件可以使用,例如:close 事件,當 Dialog 關閉時觸發,而 cancel 事件則是當使用者點擊 Dialog 中的取消按鈕時觸發,而 submit 事件則是當使用者點擊 Dialog 中的確認按鈕時觸發:

const dialog = document.querySelector('dialog');
dialog.addEventListener('close', () => {
  console.log('Dialog closed');
});
dialog.addEventListener('cancel', () => {
  console.log('Dialog cancelled');
});
dialog.addEventListener('submit', () => {
  console.log('Dialog submitted');
});

兼容性

如果舊版的瀏覽器不支援 Dialog,可以透過 dialog-polyfill 來實現,根據 README 裡面的描述可以支援到 IE9 以上的瀏覽器。使用之前也可以上 Can I use 來查看瀏覽器的支援度。

結論

使用 HTML 原生的 Dialog 可以讓我們更能專注於畫面的設計,同時也帶來有語意化的架構確保可用性及可訪問性。避免產生不必要的 CSS 樣式來管理 Dialog 的開關或位置,使用起來更直覺且易於維護。

參考資料

實作範例
MDN - The Dialog element
Modals Will Never Be The Same - HTML dialog Element