僅 CSS Tailwind CSS 模態使用原生 <dialog> 元素。響應式大小、背景和焦點陷阱。沒有用於基本使用的 JavaScript。 WCAG AA 可訪問,可與 Django、HTMX、Laravel、React 和任何堆疊配合使用。
模態元件在對焦的覆蓋視窗中顯示重要資訊或請求使用者操作。模態基於語義 HTML 對話方塊元素構建,支援動畫、可自訂定位和背景覆蓋。 Frutjam 模態系統可透過鍵盤導航和陷阱焦點完全訪問,使其成為確認、表單和警報對話框的理想選擇。
僅 CSS,無需 JavaScript。 WCAG AA 可存取且與框架無關 - 可與 Django、HTMX、Laravel、React 和任何堆疊配合使用。
| 班級 | 類型 | 描述 |
|---|---|---|
| modal | 根據 | 全螢幕對話框覆蓋容器 |
| modal-content | 修飾符 | 帶有填充和背景的內面板 |
| modal-backdrop | 修飾符 | 點選關閉背景覆蓋 |
| modal-top | 修飾符 | 將內容與螢幕頂部對齊 |
| modal-bottom | 修飾符 | 將內容與螢幕底部對齊 |
| modal-start | 修飾符 | 將內容左對齊 |
| modal-end | 修飾符 | 將內容右對齊 |
| modal-center | 修飾符 | 水平居中 |
| modal-middle | 修飾符 | 垂直居中 |
| modal-slide-up | 風格 | 上滑入口動畫 |
| modal-slide-down | 風格 | 下滑入口動畫 |
| modal-slide-start | 風格 | 從左側滑入動畫 |
| modal-slide-end | 風格 | 從右側動畫滑入 |
基本用法
將唯一的 ID 新增至 <dialog id="myModal"> HTML 元素,然後在 JavaScript 中使用該 id 呼叫 myModal.showModal() 開啟模式,並使用 myModal.close() 關閉模式。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <dialog class="modal modal-center lg:modal-middle modal-slide-end lg:modal-slide-down" id="toggleModal"> <div class="modal-content"> <div class="flex justify-between items-center gap-3"> <div class="font-medium heading-lg">Dialog modal</div> <button type="button" class="btn btn-xs btn-square btn-rounded btn-ghost" onclick="toggleModal.close()"> <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M18 6 6 18"></path> <path d="m6 6 12 12"></path> </svg> </button> </div> <div class="divider my-3"></div> <p class="para">Press Esc key or close button to close the modal</p> </div> <button type="button" class="modal-backdrop" onclick="toggleModal.close()">Close Modal via Backdrop</button> </dialog> <button type="button" class="btn btn-xs" onclick="toggleModal.showModal()">Show Modal</button> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | import { useModal } from 'frutjam/react' export default function ModalDemo() { const modal = useModal() return ( <> <button type="button" className="btn btn-xs" onClick={modal.open}>Show Modal</button> <dialog ref={modal.ref} className="modal modal-center lg:modal-middle modal-slide-end lg:modal-slide-down"> <div className="modal-content"> <div className="flex justify-between items-center gap-3"> <div className="font-medium heading-lg">Dialog modal</div> <button type="button" className="btn btn-xs btn-square btn-rounded btn-ghost" onClick={modal.close}> <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M18 6 6 18"></path> <path d="m6 6 12 12"></path> </svg> </button> </div> <div className="divider my-3"></div> <p className="para">Press Esc key or close button to close the modal</p> </div> <button type="button" className="modal-backdrop" onClick={modal.close}>Close Modal via Backdrop</button> </dialog> </> ) } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | <script setup> import { ref } from 'vue' const dialogRef = ref(null) </script> <template> <button type="button" class="btn btn-xs" @click="dialogRef.showModal()">Show Modal</button> <dialog ref="dialogRef" class="modal modal-center lg:modal-middle modal-slide-end lg:modal-slide-down"> <div class="modal-content"> <div class="flex justify-between items-center gap-3"> <div class="font-medium heading-lg">Dialog modal</div> <button type="button" class="btn btn-xs btn-square btn-rounded btn-ghost" @click="dialogRef.close()"> <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M18 6 6 18"></path> <path d="m6 6 12 12"></path> </svg> </button> </div> <div class="divider my-3"></div> <p class="para">Press Esc key or close button to close the modal</p> </div> <button type="button" class="modal-backdrop" @click="dialogRef.close()">Close Modal via Backdrop</button> </dialog> </template> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | <script> let dialog = $state(null) </script> <button type="button" class="btn btn-xs" onclick={() => dialog.showModal()}>Show Modal</button> <dialog bind:this={dialog} class="modal modal-center lg:modal-middle modal-slide-end lg:modal-slide-down"> <div class="modal-content"> <div class="flex justify-between items-center gap-3"> <div class="font-medium heading-lg">Dialog modal</div> <button type="button" class="btn btn-xs btn-square btn-rounded btn-ghost" onclick={() => dialog.close()}> <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M18 6 6 18"></path> <path d="m6 6 12 12"></path> </svg> </button> </div> <div class="divider my-3"></div> <p class="para">Press Esc key or close button to close the modal</p> </div> <button type="button" class="modal-backdrop" onclick={() => dialog.close()}>Close Modal via Backdrop</button> </dialog> |
按一下外部時關閉模態
.modal-backdrop 提供了一個可點擊的背景,當在模態內容之外點擊時,背景會關閉模態。
1 2 3 4 5 6 7 8 9 10 11 12 13 | <dialog class="modal" id="backdropModal"> <div class="modal-content"> <div class="flex justify-between items-center gap-3"> <div class="font-medium heading-lg">Dialog modal</div> </div> <div class="divider my-3"></div> <p class="para">Press Esc key or click outside to close the modal</p> </div> <button type="button" class="modal-backdrop" onclick="backdropModal.close()"> Close Modal via Backdrop </button> </dialog> <button type="button" class="btn btn-xs" onclick="backdropModal.showModal()">Show Modal</button> |
模態幻燈片動畫
Smoothly slide in and out from the top, bottom, start (left in LTR, right in RTL), or end (right in LTR, left in RTL) with the following directional utility classes: modal-slide-top, modal-slide-bottom, modal-slide-start, and modal-slide-end in the modal component. These animations improve the user experience through the use of dynamic transitions based on modal position.
從頭開始模態幻燈片(水平)
添加 modal-slide-start 實用程式以從起始側水平滑動模態;在從左到右 (LTR) 佈局中,它從左側出現;在從右到左 (RTL) 佈局中,它從右側出現。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <dialog class="modal modal-center lg:modal-middle modal-slide-start" id="slideStartModal"> <div class="modal-content"> <div class="flex justify-between items-center gap-3"> <div class="font-medium heading-lg">Slide start modal</div> <button type="button" class="btn btn-xs btn-square btn-rounded btn-ghost" onclick="slideStartModal.close()"> <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M18 6 6 18"></path> <path d="m6 6 12 12"></path> </svg> </button> </div> <div class="divider my-3"></div> <p class="para">Horizontally slides the modal in and out from the start side.</p> </div> </dialog> <button type="button" class="btn btn-xs" onclick="slideStartModal.showModal()">Show Modal</button> |
從末端開始模態滑動(水平)
在模態組件中添加 modal-slide-end 實用程序,使模態從末端水平滑動;在從左到右 (LTR) 佈局中,它從右側出現;在從右到左 (RTL) 佈局中,它從左側出現。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <dialog class="modal modal-center lg:modal-middle modal-slide-end" id="slideEndModal"> <div class="modal-content"> <div class="flex justify-between items-center gap-3"> <div class="font-medium heading-lg">Slide end modal</div> <button type="button" class="btn btn-xs btn-square btn-rounded btn-ghost" onclick="slideEndModal.close()"> <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M18 6 6 18"></path> <path d="m6 6 12 12"></path> </svg> </button> </div> <div class="divider my-3"></div> <p class="para">Horizontally slides the modal in and out from the end side.</p> </div> </dialog> <button type="button" class="btn btn-xs" onclick="slideEndModal.showModal()">Show Modal</button> |
從底部滑動(垂直):modal-slide-up
方向:從底部垂直滑入
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <dialog class="modal modal-center lg:modal-middle modal-slide-up" id="slideUpModal"> <div class="modal-content"> <div class="flex justify-between items-center gap-3"> <div class="font-medium heading-lg">Slide up modal</div> <button type="button" class="btn btn-xs btn-square btn-rounded btn-ghost" onclick="slideUpModal.close()"> <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M18 6 6 18"></path> <path d="m6 6 12 12"></path> </svg> </button> </div> <div class="divider my-3"></div> <p class="para">Vertically slides the modal in and out from the bottom.</p> </div> </dialog> <button type="button" class="btn btn-xs" onclick="slideUpModal.showModal()">Show Modal</button> |
從頂部滑動(垂直)
在模態元件中加入 modal-slide-down 公用程式以從頂部垂直滑入。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <dialog class="modal modal-center lg:modal-middle modal-slide-down" id="slideDownModal"> <div class="modal-content"> <div class="flex justify-between items-center gap-3"> <div class="font-medium heading-lg">Slide down modal</div> <button type="button" class="btn btn-xs btn-square btn-rounded btn-ghost" onclick="slideDownModal.close()"> <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M18 6 6 18"></path> <path d="m6 6 12 12"></path> </svg> </button> </div> <div class="divider my-3"></div> <p class="para">Vertically slides the modal in and out from the top.</p> </div> </dialog> <button type="button" class="btn btn-xs" onclick="slideDownModal.showModal()">Show Modal</button> |
用於通知的滑動動畫模式的範例用法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <dialog class="modal modal-end modal-top modal-slide-end" id="notificationSlideModal"> <div class="modal-content"> <div class="flex justify-between items-center gap-3"> <div class="font-medium heading-lg">Notification modal</div> <button type="button" class="btn btn-xs btn-square btn-rounded btn-ghost" onclick="notificationSlideModal.close()"> <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M18 6 6 18"></path> <path d="m6 6 12 12"></path> </svg> </button> </div> </div> </dialog> <button type="button" class="btn btn-xs" onclick="notificationSlideModal.showModal()">Show Modal</button> |
模態展示位置
預設情況下,模態元件位於螢幕中央,但可以根據使用情況使用水平類別 modal-start、modal-center 或 modal-end 以及垂直類別 modal-top、modal-middle 或 modal-bottom。佈局的設計考慮了 RTL 和 LTR 相容性,使模式能夠適應不同的語言方向和佈局。
使用modal-start、modal-center或modal-end進行水平放置,使用modal-top、modal-middle或modal-bottom進行垂直放置。這些類別應用於模態組件。
左上角模態位置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <dialog class="modal modal-start modal-top" id="topLeftModal"> <div class="modal-content"> <div class="flex justify-between items-center gap-3"> <div class="font-medium heading-lg">Modal placement top left</div> <button type="button" class="btn btn-xs btn-square btn-rounded btn-ghost" onclick="topLeftModal.close()"> <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M18 6 6 18"></path> <path d="m6 6 12 12"></path> </svg> </button> </div> <div class="divider my-3"></div> <p class="para">Modal placed at the top left corner of the screen</p> </div> <button type="button" class="modal-backdrop" onclick="topLeftModal.close()"> Close Modal via Backdrop </button> </dialog> <button type="button" class="btn btn-xs" onclick="topLeftModal.showModal()">Show Modal</button> |
頂部中心模態放置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <dialog class="modal modal-center modal-top" id="topCenterModal"> <div class="modal-content"> <div class="flex justify-between items-center gap-3"> <div class="font-medium heading-lg">Modal placement top center</div> <button type="button" class="btn btn-xs btn-square btn-rounded btn-ghost" onclick="topCenterModal.close()"> <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M18 6 6 18"></path> <path d="m6 6 12 12"></path> </svg> </button> </div> <div class="divider my-3"></div> <p class="para">Modal placed at the top center corner of the screen</p> </div> <button type="button" class="modal-backdrop" onclick="topCenterModal.close()"> Close Modal via Backdrop </button> </dialog> <button type="button" class="btn btn-xs" onclick="topCenterModal.showModal()">Show Modal</button> |
右上角模態位置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <dialog class="modal modal-end modal-top" id="topEndModal"> <div class="modal-content"> <div class="flex justify-between items-center gap-3"> <div class="font-medium heading-lg">Modal placement top end</div> <button type="button" class="btn btn-xs btn-square btn-rounded btn-ghost" onclick="topEndModal.close()"> <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M18 6 6 18"></path> <path d="m6 6 12 12"></path> </svg> </button> </div> <div class="divider my-3"></div> <p class="para">Modal placed at the top end corner of the screen</p> </div> <button type="button" class="modal-backdrop" onclick="topEndModal.close()"> Close Modal via Backdrop </button> </dialog> <button type="button" class="btn btn-xs" onclick="topEndModal.showModal()">Show Modal</button> |
居中左模態放置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <dialog class="modal modal-start modal-middle" id="startCenterModal"> <div class="modal-content"> <div class="flex justify-between items-center gap-3"> <div class="font-medium heading-lg">Modal placement left center</div> <button type="button" class="btn btn-xs btn-square btn-rounded btn-ghost" onclick="startCenterModal.close()"> <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M18 6 6 18"></path> <path d="m6 6 12 12"></path> </svg> </button> </div> <div class="divider my-3"></div> <p class="para">Modal placed at the start center corner of the screen</p> </div> <button type="button" class="modal-backdrop" onclick="startCenterModal.close()"> Close Modal via Backdrop </button> </dialog> <button type="button" class="btn btn-xs" onclick="startCenterModal.showModal()">Show Modal</button> |
居中右模態放置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <dialog class="modal modal-end modal-middle" id="endCenterModal"> <div class="modal-content"> <div class="flex justify-between items-center gap-3"> <div class="font-medium heading-lg">Modal placement right center</div> <button type="button" class="btn btn-xs btn-square btn-rounded btn-ghost" onclick="endCenterModal.close()"> <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M18 6 6 18"></path> <path d="m6 6 12 12"></path> </svg> </button> </div> <div class="divider my-3"></div> <p class="para">Modal placed at the end center corner of the screen</p> </div> <button type="button" class="modal-backdrop" onclick="endCenterModal.close()"> Close Modal via Backdrop </button> </dialog> <button type="button" class="btn btn-xs" onclick="endCenterModal.showModal()">Show Modal</button> |
左下角模態位置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <dialog class="modal modal-start modal-bottom" id="bottomStartModal"> <div class="modal-content"> <div class="flex justify-between items-center gap-3"> <div class="font-medium heading-lg">Modal placement bottom start</div> <button type="button" class="btn btn-xs btn-square btn-rounded btn-ghost" onclick="bottomStartModal.close()"> <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M18 6 6 18"></path> <path d="m6 6 12 12"></path> </svg> </button> </div> <div class="divider my-3"></div> <p class="para">Modal placed at the bottom start corner of the screen</p> </div> <button type="button" class="modal-backdrop" onclick="bottomStartModal.close()"> Close Modal via Backdrop </button> </dialog> <button type="button" class="btn btn-xs" onclick="bottomStartModal.showModal()">Show Modal</button> |
底部中心模態放置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <dialog class="modal modal-center modal-bottom" id="bottomCenterModal"> <div class="modal-content"> <div class="flex justify-between items-center gap-3"> <div class="font-medium heading-lg">Modal placement bottom center</div> <button type="button" class="btn btn-xs btn-square btn-rounded btn-ghost" onclick="bottomCenterModal.close()"> <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M18 6 6 18"></path> <path d="m6 6 12 12"></path> </svg> </button> </div> <div class="divider my-3"></div> <p class="para">Modal placed at the bottom center corner of the screen</p> </div> <button type="button" class="modal-backdrop" onclick="bottomCenterModal.close()"> Close Modal via Backdrop </button> </dialog> <button type="button" class="btn btn-xs" onclick="bottomCenterModal.showModal()">Show Modal</button> |
右下模態位置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <dialog class="modal modal-end modal-bottom" id="bottomEndModal"> <div class="modal-content"> <div class="flex justify-between items-center gap-3"> <div class="font-medium heading-lg">Modal placement bottom center</div> <button type="button" class="btn btn-xs btn-square btn-rounded btn-ghost" onclick="bottomEndModal.close()"> <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M18 6 6 18"></path> <path d="m6 6 12 12"></path> </svg> </button> </div> <div class="divider my-3"></div> <p class="para">Modal placed at the bottom center corner of the screen</p> </div> <button type="button" class="modal-backdrop" onclick="bottomEndModal.close()"> Close Modal via Backdrop </button> </dialog> <button type="button" class="btn btn-xs" onclick="bottomEndModal.showModal()">Show Modal</button> |
桌面和行動螢幕的模態響應式定位
根據您的使用案例,您可以將模態框放置在桌面或行動裝置上的任何位置,例如桌面中心和行動裝置頂部中心。
1 2 3 4 5 6 7 8 9 10 11 12 13 | <dialog class="modal modal-center modal-top lg:modal-center lg:modal-middle" id="responsiveModal"> <div class="modal-content"> <div class="flex justify-between items-center gap-3"> <div class="font-medium heading-lg">Responsive modal</div> </div> <div class="divider my-3"></div> <p class="para">Resize the modal to a small screen to see the change in modal position.</p> </div> <button type="button" class="modal-backdrop" onclick="responsiveModal.close()"> Close Modal via Backdrop </button> </dialog> <button type="button" class="btn btn-xs" onclick="responsiveModal.showModal()">Show Modal</button> |
基於語言方向的模態定位
根據語言方向(LTR 或 RTL)將模態框放置在螢幕上的任意位置。
LTR 和 RTL 中右對齊且垂直居中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | <dialog class="modal ltr:modal-end ltr:modal-middle rtl:modal-start lg:modal-middle" id="ltrModal"> <div class="modal-content"> <div class="flex justify-between items-center gap-3"> <div class="font-medium heading-lg">Responsive modal</div> </div> <div class="divider my-3"></div> <p class="para"> Changing <code>dir="rtl"</code> in the HTML will have no effect on the modal's the position because the layout is controlled by utility classes: <code>modal-end</code> for the LTR variant and <code>modal-start</code> for the RTL variant. </p> </div> <button type="button" class="modal-backdrop" onclick="ltrModal.close()"> Close Modal via Backdrop </button> </dialog> <button type="button" class="btn btn-xs" onclick="ltrModal.showModal()">Show Modal</button> |
根據螢幕尺寸和語言方向放置模態框
1 2 3 4 5 6 7 8 9 10 11 12 13 | <dialog class="modal ltr:modal-center lg:ltr:modal-start ltr:modal-top lg:ltr:modal-middle rtl:modal-center lg:rtl:modal-start rtl:modal-bottom lg:rtl:modal-middle" id="mixedModal"> <div class="modal-content"> <div class="flex justify-between items-center gap-3"> <div class="font-medium heading-lg">Responsive modal</div> </div> <div class="divider my-3"></div> <p class="para">Change the screen and screen direction to see the change in modal position.</p> </div> <button type="button" class="modal-backdrop" onclick="mixedModal.close()"> Close Modal via Backdrop </button> </dialog> <button type="button" class="btn btn-xs" onclick="mixedModal.showModal()">Show Modal</button> |
使用 Claude Code、Cursor 或其他 AI 編輯器?
Cherry MCP 為您的 AI 編輯器按需提供準確的 莫代爾 類別名稱和結構。不再有幻覺課程。