Glass Modal
A copy-paste glassmorphism component in pure HTML, CSS & vanilla JS. Zero dependencies, framework-agnostic, MIT-licensed.
GlassmorphismHTMLCSSJavaScriptany framework
Frosted Dialog
A backdrop-blur modal that scales in.
Copy into your project
HTML
<div class="nuda-glass-modal">
<button class="nuda-glass-modal__open">Open dialog</button>
<div class="nuda-glass-modal__backdrop" role="dialog" aria-modal="true" aria-label="Demo dialog">
<div class="nuda-glass-modal__panel">
<p class="nuda-glass-modal__title">Frosted Dialog</p>
<p class="nuda-glass-modal__body">A backdrop-blur modal that scales in.</p>
<button class="nuda-glass-modal__close" aria-label="Close dialog">Got it</button>
</div>
</div>
</div>CSS
/* Glass Modal
Backdrop-blur dialog that scales in.
Toggle the .nuda-glass-modal--open class on the root to show it.
Customize: --glass-modal-accent */
.nuda-glass-modal {
--glass-modal-accent: #e4ff54;
position: relative;
width: 240px;
height: 150px;
border-radius: 14px;
overflow: hidden;
background: #0e0e12;
border: 1px solid rgba(255, 255, 255, 0.08);
display: flex;
align-items: center;
justify-content: center;
}
.nuda-glass-modal__open {
padding: 9px 16px;
border: 1px solid rgba(255, 255, 255, 0.16);
border-radius: 10px;
background: rgba(255, 255, 255, 0.05);
color: #fafafa;
font: 600 0.8rem ui-sans-serif, system-ui;
cursor: pointer;
transition: background 0.2s ease;
}
.nuda-glass-modal__open:hover {
background: rgba(255, 255, 255, 0.1);
}
.nuda-glass-modal__backdrop {
position: absolute;
inset: 0;
display: flex;
align-items: center;
justify-content: center;
background: rgba(9, 9, 11, 0.5);
backdrop-filter: blur(8px);
-webkit-backdrop-filter: blur(8px);
opacity: 0;
visibility: hidden;
transition: opacity 0.3s ease, visibility 0.3s ease;
}
.nuda-glass-modal__panel {
width: 180px;
padding: 16px;
border-radius: 14px;
background: rgba(255, 255, 255, 0.08);
border: 1px solid rgba(255, 255, 255, 0.16);
box-shadow: 0 12px 40px rgba(0, 0, 0, 0.5);
transform: scale(0.85);
opacity: 0;
transition: transform 0.35s cubic-bezier(0.34, 1.56, 0.64, 1), opacity 0.3s ease;
will-change: transform, opacity;
}
.nuda-glass-modal__title {
margin: 0;
color: #fafafa;
font: 700 0.9rem ui-sans-serif, system-ui;
}
.nuda-glass-modal__body {
margin: 0.35rem 0 0.8rem;
color: rgba(250, 250, 250, 0.65);
font: 500 0.72rem ui-sans-serif, system-ui;
line-height: 1.4;
}
.nuda-glass-modal__close {
padding: 6px 12px;
border: none;
border-radius: 8px;
background: var(--glass-modal-accent);
color: #09090b;
font: 700 0.72rem ui-sans-serif, system-ui;
cursor: pointer;
}
.nuda-glass-modal--open .nuda-glass-modal__backdrop {
opacity: 1;
visibility: visible;
}
.nuda-glass-modal--open .nuda-glass-modal__panel {
transform: scale(1);
opacity: 1;
}
@media (prefers-reduced-motion: reduce) {
.nuda-glass-modal__backdrop,
.nuda-glass-modal__panel { transition: opacity 0.2s ease, visibility 0.2s ease; }
.nuda-glass-modal__panel { transform: none; }
}JavaScript
/* Glass Modal — vanilla JS
Opens and closes the frosted dialog. */
(function () {
document.querySelectorAll(".nuda-glass-modal").forEach(function (root) {
var open = root.querySelector(".nuda-glass-modal__open");
var close = root.querySelector(".nuda-glass-modal__close");
if (open) open.addEventListener("click", function () {
root.classList.add("nuda-glass-modal--open");
});
if (close) close.addEventListener("click", function () {
root.classList.remove("nuda-glass-modal--open");
});
});
})();How to use Glass Modal
Paste the HTML where you need it and the CSS into a global stylesheet (or a <style> tag). Every class is prefixed nuda- so it never collides with Tailwind or your own styles. Tweak the CSS custom properties to match your design system.
Works in React, Vue, Svelte, Astro, Next.js, Nuxt, Laravel Blade, Django, Rails — or a single .html file. No npm install, no build step.