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
What's included
Features
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
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.