Popover
A copy-paste modals & overlays component in pure HTML, CSS & vanilla JS. Zero dependencies, framework-agnostic, MIT-licensed.
Modals & OverlaysHTMLCSSJavaScriptany framework
Copy into your project
HTML
<div class="nuda-popover">
<button class="nuda-popover__trigger">Click me</button>
<div class="nuda-popover__content">
<div class="nuda-popover__arrow"></div>
<h4 class="nuda-popover__title">Popover Title</h4>
<p class="nuda-popover__body">Additional information goes here.</p>
</div>
</div>CSS
/* Popover
Click-triggered popover with arrow.
Customize: --pop-bg, --pop-border */
.nuda-popover {
position: relative;
display: inline-block;
}
.nuda-popover__trigger {
background: rgba(228, 255, 84, 0.1);
border: 1px solid rgba(228, 255, 84, 0.2);
border-radius: 8px;
padding: 0.5rem 1rem;
color: #e4ff54;
font-size: 0.85rem;
cursor: pointer;
}
.nuda-popover__content {
position: absolute;
bottom: calc(100% + 8px);
left: 50%;
transform: translateX(-50%) translateY(4px);
background: #1a1a1a;
border: 1px solid rgba(255, 255, 255, 0.08);
border-radius: 10px;
padding: 0.75rem 1rem;
min-width: 180px;
opacity: 0;
visibility: hidden;
transition: opacity 0.2s ease, transform 0.2s ease, visibility 0.2s ease;
z-index: 100;
}
.nuda-popover.is-open .nuda-popover__content {
opacity: 1;
visibility: visible;
transform: translateX(-50%) translateY(0);
}
.nuda-popover__arrow {
position: absolute;
bottom: -5px;
left: 50%;
transform: translateX(-50%);
width: 0;
height: 0;
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-top: 6px solid #1a1a1a;
}
.nuda-popover__title {
font-size: 0.85rem;
font-weight: 700;
color: #fff;
margin: 0 0 0.25rem;
}
.nuda-popover__body {
font-size: 0.78rem;
color: #999;
margin: 0;
}
@media (prefers-reduced-motion: reduce) {
.nuda-popover__content { transition: none; }
}JavaScript
/* Popover — Toggle with .is-open class */
(function () {
var popovers = document.querySelectorAll('.nuda-popover');
popovers.forEach(function (pop) {
var trigger = pop.querySelector('.nuda-popover__trigger');
if (!trigger) return;
trigger.addEventListener('click', function (e) {
e.stopPropagation();
pop.classList.toggle('is-open');
});
document.addEventListener('click', function (e) {
if (!pop.contains(e.target)) {
pop.classList.remove('is-open');
}
});
});
})();How to use Popover
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.