網頁 Modal 視窗的現代寫法
| | | 0 | |
這篇說的 Modal 視窗 (Modal Dialog) 是指在現有網頁開啟一個較小視窗,強迫使用者必須完成閱讀或操作才能回到原網頁繼續操作,常用於警示、確認、開啟自訂選擇器之類的情境。打從 IE6 開始,設計網頁時我就很常使用 Modal 視窗,一路從 IE 時代的 showModalDialog、jQuery UI Dialog、Bootstrap Modal、Kendo UI Dialog、SweetAlert2,一直到四年前研發 showModalDialog 完整替代方案,也算得上經驗豐富,
而隨著開始用 Github Copilot 輔助開發,冷不防就看到 AI 露一手幾乎不用寫 JavaScript 的精巧 Modal 視窗寫法,讓我有自己還在媽媽十塊的羞愧感,這篇就來整理兩種 Low Code 的網頁 Modal 視窗寫法。
我用以下網頁示範,點日文等級旁的小藍 i 會彈出日本檢定的級數說明,以 Modal 視窗形式呈現,點紅 X 或遮罩空白處可關閉。

使用 CSS 動態切換
第一種做法是在網頁最後疊加一個內含 Modal 內容的 <div class="tips-modal">,設定 position: fixed; inset: 0; background: rgba(0, 0, 0, 0.45); 佔滿全頁(若有其他 position: absolute 元素再用 z-index 上移) 以半透明地蓋在原網頁上。一開始網頁設定 ‵display: none隱藏,點選小藍 i 時,為 .tips-modal 加上 .is-open 樣式,.is-open 會設定display: flex` 讓 div.tips-modal 顯現出來。要關閉則將 .is-open 樣式移除即可:
<body>
<table class="form">
<tr>
<td class="hdr">
日文等級
<i class="tip-button" onclick="document.querySelector('.tips-modal').classList.add('is-open')"></i>
</td>
<td>
<select>
<option value="N1">N1</option>
<option value="N2">N2</option>
<option value="N3">N3</option>
<option value="N4">N4</option>
<option value="N5">N5</option>
</select>
</td>
</tr>
</table>
<div class="tips-modal" onclick="if(event.target==this)this.classList.remove('is-open')">
<div class="content">
<table>
<thead>
<tr>
<th>級數</th>
<th>程度</th>
<th>
說明
<i class="close-button" onclick="document.querySelector('.tips-modal').classList.remove('is-open')"></i>
</th>
</tr>
</thead>
<tbody>
<tr>
<td>N1</td>
<td>高階</td>
<td>可理解廣泛情境的日語,如閱讀新聞、評論、論說文等複雜文章,並能流利會話。</td>
</tr>
<!-- 省略 -->
</tbody>
</table>
</div>
</div>
</body>

HTML 原生 <dialog>
2022 起主流瀏覽器(Chrome 98+、Firefox 98+、Safari 15.4+)已全面支援 <dialog> 元素,讓我們能用更少的程式碼及 CSS 設定實現 Modal 視窗效果。
<dialog> 的寫法跟 CSS 切換式幾乎一模一樣,差別在可以少設定很多 CSS 樣式(遮罩樣式由 ::backgrop 偽元素控制),加上瀏覽器內建支持,可確保永遠在最上層(不需煩惱 z-index)、Tab 切換焦點操作限定在 dialog 內、支援 Escape 鍵關閉... 等,方便性更上一層樓。
<body>
<table class="form">
<tr>
<td class="hdr">
日文等級
<i class="tip-button" onclick="document.getElementById('tips-dialog').showModal()"></i>
</td>
<td>
<select>
<option value="N1">N1</option>
<option value="N2">N2</option>
<option value="N3">N3</option>
<option value="N4">N4</option>
<option value="N5">N5</option>
</select>
</td>
</tr>
</table>
<dialog id="tips-dialog" onclick="if(event.target===this)this.close()">
<div class="content">
<table>
<thead>
<tr>
<th>級數</th>
<th>程度</th>
<th>
說明
<i class="close-button" onclick="document.getElementById('tips-dialog').close()"></i>
</th>
</tr>
</thead>
<tbody>
<tr>
<td>N1</td>
<td>高階</td>
<td>可理解廣泛情境的日語,如閱讀新聞、評論、論說文等複雜文章,並能流利會話。</td>
</tr>
<!-- 省略 -->
</tbody>
</table>
</div>
</dialog>
</body>

綜合比較
比較上述兩種做法,瀏覽器內建支援的 <dialog> 以 CSS 及 JavaScript 更簡潔、不受 z-index 影響、Tab 焦點受限、支援 Escape 鍵... 等優勢略勝一籌,CSS 的優勢在於可自訂動畫、佈局、樣式、可做滑入、淡入等過場效果,在大部分應用情境可優先考量使用 <dialog>。
Explores two low‑code ways to build modal dialogs: a CSS toggle overlay and the native HTML dialog element. Compares simplicity, accessibility, browser support, and customization, concluding dialog is usually the better modern choice with less JavaScript.
Comments
Be the first to post a comment