Modal Snippets — Free HTML CSS JS Modals, Banners & Notifications

32 modal components · Dialog, Toast, Lightbox, Bottom Sheet, Alert Banners, Side Drawer, Popover, Cookie Banner, Command Palette · Exports to React, Vue, Angular & Tailwind

Share & Support

What's included

Features

Modal: backdrop-filter blur(8px) + scale(0.95→1) + opacity entry animation
Modal: click-outside + ESC keydown + × button — 3 independent close mechanisms
Cookie banner: position:fixed slideUp entry, slideDown exit, animationend .remove()
Toast: dynamic createElement per toast, 3 semantic types, 2.8s auto-dismiss
Toast: stacking via flex column, each toast independent with its own animationend
Command palette: Cmd/Ctrl+K shortcut, grouped commands, substring search, arrow nav
All components: pointer-events:none in hidden state — no invisible click blocking

About this tool

Modal Snippets — Free Dialogs, Cookie Banners, Toast Notifications & Command Palette

Modals, overlays, banners, and toast notifications interrupt or augment the page to communicate critical information or capture user decisions. They are among the most technically tricky UI patterns because they must appear, animate, disappear cleanly, and never leave invisible elements blocking clicks. This collection covers the four most common overlay patterns in web development — all with proper animation cleanup.

Every snippet uses vanilla JavaScript and CSS animations. No library dependencies. The animationend event pattern is used throughout to ensure elements are fully removed from the DOM after exit animations complete.

Modal Dialog uses a backdrop with backdrop-filter: blur(8px) and a slight dark background tint. The dialog itself enters with a scale(0.95) → scale(1) + opacity 0 → 1 CSS animation. Three close mechanisms are implemented: the × button, clicking the backdrop overlay, and pressing ESC. On close, a reverse animation plays and animationend removes the element. pointer-events: none on the closed state prevents invisible elements from blocking page interactions.

Cookie Consent Banner slides up from the bottom via a CSS keyframe animation. It is position: fixed at the bottom of the viewport. The accept() and decline() functions set localStorage flags and then trigger a slide-down exit animation — animationend fires and calls banner.remove() for full DOM cleanup. On page load, the banner checks localStorage first and skips rendering if consent is already stored.

Toast Notification System creates each toast dynamically — document.createElement is called on each showToast() invocation. Three semantic types are supported: success (green with ✓), error (red with ✗), and info (blue with ℹ). Each toast slides in from the right, auto-dismisses after 2.8 seconds via setTimeout, and slides back out before the animationend listener removes it from the DOM. Multiple toasts stack in a fixed flex column — each is independent.

Command Palette opens on Cmd+K (Mac) or Ctrl+K (Windows/Linux). The search input filters commands by substring match on name and description. Commands are organised in named groups (Navigation, Actions, Settings) and rendered with group headings. Arrow Up/Down key navigation moves through visible results. Enter activates the highlighted command. ESC or clicking outside closes the palette. The palette renders above all other content via a high z-index overlay.

All four components share the same animationend cleanup pattern — a critical technique for any animated show/hide UI element.

Real-world uses

Common Use Cases

Confirm destructive actions before permanent data loss
Modal with a red confirm button for delete, remove, or reset operations. Multiple close mechanisms (ESC, overlay click, × button) make it easy to cancel. The backdrop blur reduces distraction and focuses the decision.
GDPR and cookie consent compliance banners
Cookie consent banner required on any site using analytics, advertising, or tracking cookies in EU/UK/California jurisdictions. Accept and decline buttons with localStorage persistence. The slide-up animation draws attention without blocking the page, and the slide-down exit cleans up cleanly.
Async operation feedback and system notifications
Toast notifications for save confirmations ("Profile saved"), API errors ("Connection failed — try again"), clipboard copy feedback, and background job completion notices. The three semantic types (success/error/info) cover every standard notification case without per-instance styling.
Keyboard-first command interfaces for power users
Command palette for developer tools, productivity apps, and any interface where keyboard-first users want to trigger actions without navigating menus. Cmd+K opens instantly, grouped commands help users browse, and fuzzy search reduces the typed input needed to find any command.
Study the animationend DOM cleanup pattern for all overlays
The animationend event fires once when a CSS animation completes and removes the element from the DOM entirely. This pattern is used in all four components — it prevents invisible zero-size elements from intercepting clicks after the exit animation finishes, a bug that is easy to miss and hard to debug.
Wire toast notifications to API responses throughout your app
Call showToast("Saved", "success") after a successful API call, showToast("Network error", "error") on fetch failure, and showToast("Processing in background", "info") for async operations. The three-type system gives users clear semantic feedback about outcomes without custom styling per call site.

Got questions?

Frequently Asked Questions

Setting display: none immediately cuts off the exit animation — the element disappears without the closing animation playing. The animationend pattern lets the full CSS exit animation play, then fires the cleanup. Without this, setting display: none or opacity: 0 alone leaves the element in the DOM at zero opacity — a transparent element that is still in the event path and will block clicks on whatever is behind it. animationend + element.remove() ensures the element is fully gone from both the visual layer and the event path.

In the accept() function: localStorage.setItem("cookie_consent", "accepted") with a value and timestamp. On every page load, read localStorage.getItem("cookie_consent") — if the key exists and is not expired, call hideBanner() immediately before the banner renders. For a server-rendered app, check a cookie server-side instead and conditionally include the banner HTML — this prevents the banner from appearing and then disappearing on load.

The .toasts container uses display: flex; flex-direction: column-reverse; gap: 8px; and is position: fixed at the bottom-right corner. Each new toast is appended and appears above previous ones. Each toast manages its own 2.8-second auto-dismiss independently — one dismissing does not affect others. To limit the number of visible toasts, check document.querySelectorAll(".toast").length before creating a new one and remove the oldest if the count exceeds your limit (e.g. 3).

Add objects to the COMMANDS array at the top of the script: { group: "My Group", icon: "⭐", name: "Command Name", desc: "Short description", shortcut: "⌘N" }. The render function automatically groups commands by the group property and displays them with the icon, name, description, and shortcut. Add as many groups and commands as needed — the search filter and arrow navigation adapt automatically to the new command count.