|$ curl https://forge-ai.dev/api/markdown?path=docs/components/modals
$cat docs/modals.md
updated Recently·20 min read·published

Modals

CSSHTMLTailwindBootstrapUIAdvanced🎯Free Tools
Introduction

Modal dialogs focus user attention on a specific task, form, or message without leaving the current page. This guide covers production-ready modal patterns in plain HTML/CSS, Tailwind CSS, and Bootstrap — including confirmation dialogs, forms, alerts, slide-out panels, sizing, and accessibility.

info

Always use role="dialog" and aria-modal="true" on the modal container, and bind the title with aria-labelledby. Trap focus inside the modal while it is open.
Confirmation Dialog

A centered confirmation dialog with backdrop blur, close controls, and destructive action buttons. Click the trigger to open, then close via the backdrop, Escape key, or action buttons.

confirmation-dialog
Live
untitled.html
HTML
1<div class="modal-demo">
2 <button class="open-btn" data-open="modal-confirm">
3 Open Modal
4 </button>
5 <div class="modal-wrapper" id="modal-confirm">
6 <div class="modal-backdrop" data-close>
7 </div>
8 <div class="modal" role="dialog" aria-modal="true" aria-labelledby="confirm-title">
9 <div class="modal-header">
10 <h3 id="confirm-title" class="modal-title">
11 Confirm Action
12 </h3>
13 <button class="modal-close" data-close aria-label="Close">
14
15 </button>
16 </div>
17 <p class="modal-desc">
18 Are you sure you want to delete this item? This action cannot be undone. All associated data will be permanently removed.
19 </p>
20 <div class="modal-footer">
21 <button class="btn btn-secondary" data-close>
22 Cancel
23 </button>
24 <button class="btn btn-danger">
25 Delete
26 </button>
27 </div>
28 </div>
29 </div>
30</div>
preview
Form Modal

Modals are a common home for compact forms like sign-in, subscribe, or feedback. Keep labels visible, use clear validation, and close the modal only after a successful submission.

form-modal
Live
untitled.html
HTML
1<div class="modal-demo">
2 <button class="open-btn" data-open="modal-form">
3 Sign In
4 </button>
5 <div class="modal-wrapper" id="modal-form">
6 <div class="modal-backdrop" data-close>
7 </div>
8 <div class="modal" role="dialog" aria-modal="true" aria-labelledby="form-title">
9 <div class="modal-header">
10 <h3 id="form-title" class="modal-title">
11 Sign In
12 </h3>
13 <button class="modal-close" data-close aria-label="Close">
14
15 </button>
16 </div>
17 <form class="modal-form">
18 <label>
19 Email
20 <input type="email" placeholder="you@example.com" required />
21 </label>
22 <label>
23 Password
24 <input type="password" placeholder="••••••••" required />
25 </label>
26 <button type="submit" class="submit-btn">
27 Continue
28 </button>
29 </form>
30 </div>
31 </div>
32</div>
preview
Alert & Status Modal

Status modals communicate the result of an action. Use an inline SVG icon, a concise message, and a single primary action to dismiss.

status-modal
Live
untitled.html
HTML
1<div class="modal-demo">
2 <button class="open-btn" data-open="modal-status">
3 Show Status
4 </button>
5 <div class="modal-wrapper" id="modal-status">
6 <div class="modal-backdrop" data-close>
7 </div>
8 <div class="modal alert-modal" role="dialog" aria-modal="true" aria-labelledby="status-title">
9 <div class="alert-icon">
10 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" width="32" height="32">
11 <path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/>
12 <polyline points="22 4 12 14.01 9 11.01"/>
13 </svg>
14 </div>
15 <h3 id="status-title" class="modal-title centered">
16 Payment Successful
17 </h3>
18 <p class="modal-desc centered">
19 Your transaction has been processed. A receipt has been sent to your email.
20 </p>
21 <div class="modal-footer centered">
22 <button class="btn btn-primary" data-close>
23 Done
24 </button>
25 </div>
26 </div>
27 </div>
28</div>
preview
Slide-Out Panel

Slide-out panels enter from an edge and work well for detail views, settings, or shopping carts. Add a backdrop and close on Escape or backdrop click for a native feel.

slide-panel
Live
untitled.html
HTML
1<div class="panel-demo">
2 <button class="open-btn" data-open="panel-settings">
3 Open Settings
4 </button>
5 <div class="panel-wrapper" id="panel-settings">
6 <div class="panel-backdrop" data-close>
7 </div>
8 <div class="panel" role="dialog" aria-modal="true" aria-labelledby="panel-title">
9 <div class="panel-header">
10 <h3 id="panel-title" class="panel-title">
11 Settings
12 </h3>
13 <button class="panel-close" data-close aria-label="Close panel">
14
15 </button>
16 </div>
17 <div class="panel-body">
18 <div class="panel-row">
19 <span>
20 Dark mode
21 </span>
22 <input type="checkbox" checked />
23 </div>
24 <div class="panel-row">
25 <span>
26 Notifications
27 </span>
28 <input type="checkbox" checked />
29 </div>
30 <div class="panel-row">
31 <span>
32 Auto-save
33 </span>
34 <input type="checkbox" />
35 </div>
36 </div>
37 </div>
38 </div>
39</div>
preview
HTML Structure

A semantic modal follows a predictable structure: backdrop overlay, dialog container with role="dialog", header with title and close button, content area, and footer with actions. Bind the title with aria-labelledby and return focus to the trigger on close.

modal-structure.html
HTML
1<div class="modal-backdrop"><!-- background overlay --></div>
2<div class="modal" role="dialog" aria-modal="true"
3 aria-labelledby="dialog-title">
4 <div class="modal-header">
5 <h3 id="dialog-title" class="modal-title">
6 Confirm Action
7 </h3>
8 <button class="modal-close" aria-label="Close">✕</button>
9 </div>
10 <div class="modal-body">
11 <p>Are you sure you want to proceed?</p>
12 </div>
13 <div class="modal-footer">
14 <button class="btn">Cancel</button>
15 <button class="btn btn-primary">Confirm</button>
16 </div>
17</div>
Accessibility

Modals can easily trap or disorient keyboard and screen-reader users. Apply these patterns to keep dialogs usable for everyone.

  • Use a real <button> for the trigger, not a div or link styled as a button.
  • Add role="dialog" and aria-modal="true" so assistive tech identifies the boundary.
  • Bind the title to the dialog with aria-labelledby, or use aria-label when no visible title exists.
  • Trap focus inside the open modal — Tab should cycle through focusable modal elements only.
  • Close on Escape key and backdrop click, but not when the user clicks inside the dialog.
  • Return focus to the trigger element when the modal closes.
  • Keep the modal title focusable or move focus to the first focusable control on open.
  • Disable background page scrolling while a modal is open to prevent loss of context.
Best Practices
  • Keep modals focused on a single task or message — avoid long scrolling content.
  • Use a clearly labeled close control in the header and a primary action in the footer.
  • Animate entrance with opacity and transform, keeping transitions brief (200-300ms).
  • Avoid stacking multiple modals; use a queue or replace the current dialog instead.
  • Test modals at 320px wide viewports to ensure content does not overflow.
  • Reserve modals for decisions that block the current workflow; inline content is often better for non-blocking information.
Motion & Micro-interactions

Modal animations should guide attention without stealing it. The most effective pattern pairs a fading backdrop with a dialog that scales up slightly and slides in from above. Add subtle press and lift states to the trigger and close controls so the interaction feels tactile. Keep durations between 200ms and 300ms, use an easing curve that decelerates, and coordinate both entering and leaving states so the modal does not vanish instantly.

modal-motion
Live
untitled.html
HTML
1<div class="modal-demo">
2 <button class="trigger-btn" data-open="modal-motion">
3 <svg class="trigger-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" width="16" height="16">
4 <path d="M12 5v14M5 12h14"/>
5 </svg>
6 Open Modal
7 </button>
8 <div class="modal-wrapper" id="modal-motion">
9 <div class="modal-backdrop" data-close>
10 </div>
11 <div class="modal motion-modal" role="dialog" aria-modal="true" aria-labelledby="motion-title">
12 <div class="modal-header">
13 <h3 id="motion-title" class="modal-title">
14 Deploy Changes
15 </h3>
16 <button class="modal-close" data-close aria-label="Close">
17 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" width="14" height="14">
18 <path d="M18 6L6 18M6 6l12 12"/>
19 </svg>
20 </button>
21 </div>
22 <p class="modal-desc">
23 Ready to push the latest build to production. The deployment will take about 30 seconds.
24 </p>
25 <div class="modal-footer">
26 <button class="btn btn-secondary" data-close>
27 Cancel
28 </button>
29 <button class="btn btn-primary glow">
30 Deploy
31 </button>
32 </div>
33 </div>
34 </div>
35</div>
preview
📝

note

Respect prefers-reduced-motion. Wrap entrance and exit keyframes in a media query so users who opt out of animation see an instant, stable dialog. In Tailwind, combine motion-safe: with the animation utility, or disable animations globally inside the reduced-motion query.

Community

Get help on Slack, Discord or VIP

Stuck on a guide? Join the community and ask.