Dropdown Menu
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-dropdown">
<button class="nuda-dropdown__trigger" aria-haspopup="true" aria-expanded="false">
Menu ▾
</button>
<div class="nuda-dropdown__menu" role="menu">
<a href="#" class="nuda-dropdown__item" role="menuitem">Profile</a>
<a href="#" class="nuda-dropdown__item" role="menuitem">Settings</a>
<hr class="nuda-dropdown__divider" />
<a href="#" class="nuda-dropdown__item nuda-dropdown__item--danger" role="menuitem">Logout</a>
</div>
</div>CSS
/* Dropdown Menu
Animated dropdown with scale + fade entrance.
Customize: --dropdown-bg, --dropdown-accent */
.nuda-dropdown {
position: relative;
display: inline-block;
}
.nuda-dropdown__trigger {
background: rgba(255, 255, 255, 0.06);
border: 1px solid rgba(255, 255, 255, 0.1);
border-radius: 8px;
padding: 0.5rem 1rem;
color: #ccc;
font-size: 0.85rem;
cursor: pointer;
transition: background 0.2s;
}
.nuda-dropdown__trigger:hover {
background: rgba(255, 255, 255, 0.1);
}
.nuda-dropdown__menu {
position: absolute;
top: calc(100% + 4px);
left: 0;
min-width: 160px;
background: #141414;
border: 1px solid rgba(255, 255, 255, 0.08);
border-radius: 10px;
padding: 0.25rem;
opacity: 0;
visibility: hidden;
transform: translateY(-6px) scale(0.97);
transform-origin: top left;
transition: opacity 0.2s ease, transform 0.2s ease, visibility 0.2s ease;
z-index: 100;
}
.nuda-dropdown.is-open .nuda-dropdown__menu {
opacity: 1;
visibility: visible;
transform: translateY(0) scale(1);
}
.nuda-dropdown__item {
display: block;
padding: 0.5rem 0.75rem;
border-radius: 6px;
color: #ccc;
font-size: 0.8rem;
text-decoration: none;
transition: background 0.15s;
}
.nuda-dropdown__item:hover {
background: rgba(255, 255, 255, 0.06);
color: #fff;
}
.nuda-dropdown__item--danger { color: #f87171; }
.nuda-dropdown__item--danger:hover { background: rgba(248, 113, 113, 0.08); }
.nuda-dropdown__divider {
border: none;
height: 1px;
background: rgba(255, 255, 255, 0.06);
margin: 0.25rem 0;
}
@media (prefers-reduced-motion: reduce) {
.nuda-dropdown__menu { transition: none; }
}JavaScript
/* Dropdown Menu — Toggle with .is-open class */
(function () {
var dropdowns = document.querySelectorAll('.nuda-dropdown');
dropdowns.forEach(function (dropdown) {
var trigger = dropdown.querySelector('.nuda-dropdown__trigger');
if (!trigger) return;
trigger.addEventListener('click', function () {
var isOpen = dropdown.classList.toggle('is-open');
trigger.setAttribute('aria-expanded', String(isOpen));
});
document.addEventListener('click', function (e) {
if (!dropdown.contains(e.target)) {
dropdown.classList.remove('is-open');
trigger.setAttribute('aria-expanded', 'false');
}
});
});
})();How to use Dropdown Menu
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.