SolutionsCase StudiesAI ToolsResourcesAboutContact
Get Your Free AI Automation Audit Book a Free 30-Minute Strategy Call
Playground~/frontend Open editor

~/css/tailwind-modals

6 Tailwind Modals

0 Tailwind6 with JSPublished 2026-10-04Free · no sign-up

Six modal designs that pair the native dialog element with Tailwind classes: a delete confirmation, a mobile bottom sheet, a slide-over filter panel, a success message, a newsletter prompt and a non-blocking cookie banner.

01. Tailwind Confirm Dialog

TailwindDialog

A destructive-action confirmation using the native dialog element styled with Tailwind, including the backdrop: variant for the dimmed overlay. showModal() gives focus trapping and Escape to close for free, and the action buttons sit in a method="dialog" form.

View code
<button id="twm-o" class="rounded-lg bg-red-600 px-4 py-2.5 font-bold text-white">Delete project</button>
<dialog id="twm" aria-labelledby="twm-t" class="w-[min(380px,90vw)] rounded-2xl p-6 text-slate-600 shadow-2xl backdrop:bg-slate-950/60 backdrop:backdrop-blur-sm">
  <h2 id="twm-t" class="mb-2 text-lg font-bold text-slate-900">Delete this project?</h2>
  <p class="mb-5 text-[15px] leading-relaxed">It will be removed for everyone on your team. This cannot be undone.</p>
  <form method="dialog" class="flex justify-end gap-2">
    <button class="rounded-lg border border-slate-300 px-4 py-2 text-sm font-bold text-slate-700">Cancel</button>
    <button class="rounded-lg bg-red-700 px-4 py-2 text-sm font-bold text-white">Delete</button>
  </form>
</dialog>
const twm = document.getElementById('twm');
document.getElementById('twm-o').addEventListener('click', () => twm.showModal());
twm.addEventListener('click', e => { if (e.target === twm) twm.close(); });
twm.showModal();

02. Tailwind Bottom Sheet

TailwindMobile

A share sheet pinned to the bottom of the screen with rounded top corners and a grab handle, built on dialog with Tailwind margin utilities to anchor it. Large tap targets in a three-column grid suit thumbs on phones.

View code
<button id="tws-o" class="rounded-full bg-slate-900 px-5 py-2.5 font-bold text-white">Share</button>
<dialog id="tws-d" aria-labelledby="tws-t" class="m-0 mt-auto w-full max-w-none rounded-t-3xl p-5 pt-3 sm:mx-auto sm:max-w-md backdrop:bg-slate-900/40">
  <span class="mx-auto mb-4 block h-1.5 w-10 rounded-full bg-slate-300" aria-hidden="true"></span>
  <h2 id="tws-t" class="mb-4 font-bold text-slate-900">Share this product</h2>
  <div class="mb-4 grid grid-cols-3 gap-2 text-sm font-semibold text-slate-800"><button class="rounded-xl bg-slate-100 py-4">Copy link</button><button class="rounded-xl bg-slate-100 py-4">Email</button><button class="rounded-xl bg-slate-100 py-4">Message</button></div>
  <form method="dialog"><button class="w-full rounded-xl border border-slate-300 py-3 font-bold text-slate-800">Close</button></form>
</dialog>
const sd = document.getElementById('tws-d');
document.getElementById('tws-o').addEventListener('click', () => sd.showModal());
sd.addEventListener('click', e => { if (e.target === sd) sd.close(); });
sd.showModal();

03. Tailwind Slide-Over Panel

TailwindDrawer

A full-height panel on the right edge for filters or a cart, made from dialog with ml-auto and h-full. The header, scrollable middle and footer form a flex column, so the checkout button stays visible however long the list gets.

View code
<button id="twd-o" class="rounded-lg border border-slate-700 bg-slate-900 px-4 py-2.5 font-bold text-white">Filters</button>
<dialog id="twd" aria-labelledby="twd-t" class="m-0 ml-auto h-full max-h-none w-[min(340px,86vw)] bg-slate-950 p-0 text-slate-300 backdrop:bg-black/60 open:flex open:flex-col">
  <header class="flex items-center justify-between border-b border-slate-800 px-5 py-4"><h2 id="twd-t" class="text-lg font-bold text-white">Filters</h2><form method="dialog"><button aria-label="Close filters" class="h-8 w-8 rounded-full bg-slate-800 text-lg text-white">&times;</button></form></header>
  <div class="flex-1 space-y-3 overflow-y-auto px-5 py-4 text-sm">
    <label class="flex items-center gap-3"><input type="checkbox" class="accent-emerald-400" checked> In stock</label>
    <label class="flex items-center gap-3"><input type="checkbox" class="accent-emerald-400"> On sale</label>
    <label class="flex items-center gap-3"><input type="checkbox" class="accent-emerald-400"> Handmade</label>
  </div>
  <footer class="border-t border-slate-800 p-5"><button class="w-full rounded-lg bg-emerald-400 py-2.5 font-bold text-emerald-950">Show 24 results</button></footer>
</dialog>
const td = document.getElementById('twd');
document.getElementById('twd-o').addEventListener('click', () => td.showModal());
td.addEventListener('click', e => { if (e.target === td) td.close(); });
td.showModal();

04. Tailwind Success Modal

TailwindFeedback

A confirmation modal with a large tick icon in a tinted circle, a heading, a short message and one primary action that receives focus when it opens. The icon is an inline SVG hidden from screen readers since the heading already says what happened.

View code
<dialog id="twok" aria-labelledby="twok-t" class="w-[min(360px,90vw)] rounded-3xl p-7 text-center backdrop:bg-slate-900/40">
  <span class="mx-auto mb-4 grid h-16 w-16 place-items-center rounded-full bg-green-100" aria-hidden="true"><svg class="h-8 w-8 text-green-700" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12.5l4.5 4.5L19 7.5"/></svg></span>
  <h2 id="twok-t" class="mb-2 text-xl font-bold text-slate-900">Payment received</h2>
  <p class="mb-6 text-[15px] leading-relaxed text-slate-600">Your receipt is on its way to your inbox.</p>
  <form method="dialog"><button autofocus class="w-full rounded-xl bg-green-700 py-3 font-bold text-white hover:bg-green-800">View order</button></form>
</dialog>
document.getElementById('twok').showModal();

05. Tailwind Newsletter Modal

TailwindMarketing

A two-column signup prompt with a decorative art panel and an email form, collapsing to one column on phones with sm:grid-cols-2. It has a clear close button in the corner, and the open: variant applies the grid only when the dialog is open.

View code
<dialog id="twn" aria-labelledby="twn-t" class="w-[min(560px,94vw)] overflow-hidden rounded-2xl bg-slate-950 p-0 text-slate-400 backdrop:bg-black/60 open:grid sm:open:grid-cols-[1fr_1.3fr]">
  <div class="h-24 [background:radial-gradient(circle_at_30%_30%,#f59e0b,transparent_55%),radial-gradient(circle_at_70%_70%,#ec4899,transparent_55%),#1b1630] sm:h-auto" aria-hidden="true"></div>
  <form method="dialog" class="relative grid gap-2 p-6 pt-8">
    <button value="close" aria-label="Close" class="absolute right-3 top-3 h-8 w-8 rounded-full bg-slate-800 text-white">&times;</button>
    <h2 id="twn-t" class="text-xl font-bold leading-tight text-white">Get 10% off your first order</h2>
    <p class="mb-1 text-sm">New pieces every month, no spam.</p>
    <label class="text-sm font-semibold text-slate-200">Email<input type="email" autocomplete="email" class="mt-1.5 w-full rounded-lg border border-slate-700 bg-slate-900 px-3 py-2.5 font-normal text-white outline-none focus:border-amber-400"></label>
    <button value="join" class="rounded-lg bg-amber-400 py-2.5 font-bold text-amber-950">Join the list</button>
  </form>
</dialog>
document.getElementById('twn').showModal();

About these Tailwind Modals

Style the backdrop

Tailwind's backdrop: variant styles the dialog's ::backdrop, so backdrop:bg-slate-950/60 backdrop:backdrop-blur-sm dims and blurs the page behind a modal with no extra element.

Layout only when open

A closed dialog must stay hidden. The open: variant applies flex or grid only while the dialog has the open attribute, as in the slide-over and newsletter demos, so the dialog never shows by accident.

Positioning sheets and drawers

Dialogs are centred with automatic margins. m-0 mt-auto pins the bottom sheet to the bottom edge, and m-0 ml-auto h-full turns the slide-over into a full-height right panel.

Behaviour comes from dialog

showModal() traps focus, makes the page inert and closes on Escape. Buttons inside form method="dialog" close it without any extra script.

Frequently asked questions

Do I need a modal library?

No. The dialog element covers focus, Escape and the backdrop in every current browser.

Why do the previews open on load?

So you can see each design. In your site, call showModal() from a click.

Do these need Tailwind plugins?

No. backdrop: and open: are built-in variants.