JSFiddle - React, Tailwind, and code Playground
by Suliman123
HTML
<nav>
<ul class="nav-menu">
<li>
<a href="#" data-toggle="dropdown">About</a>
<ul class="dropdown">
<li><a href="/foo.html">Hello World</a></li>
<li><a href="/bar.html">Bar</a></li>
</ul>
</li>
<li><a href="#">Services</a></li>
</ul>
</nav>
CSS
body {
background: #efefef;
}
ul {
list-style: none;
}
a {
text-decoration: none;
}
nav {
width: 300px;
}
.nav-menu {
background-color: orange;
display: flex;
justify-content: center;
}
.nav-menu > li {
position: relative;
}
.nav-menu > li > a {
display: flex;
align-items: center;
background: transparent;
color: blue;
padding: 10px 15px;
border-radius: 4px;
transition: background 0.3s ease;
white-space: nowrap;
}
.nav-menu > li > a:hover {
color: black;
}
.dropdown {
list-style: none;
padding: 6px 8px;
margin: 0;
position: absolute;
top: 100%;
left: 0;
width: 100%;
background: #ffffff;
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.15);
border-radius: 6px;
overflow: hidden;
transform: scaleY(0);
transform-origin: top;
opacity: 0;
transition: transform 0.3s ease, opacity 0.3s ease;
z-index: 1000;
}
.nav-menu li:hover .dropdown {
transform: scaleY(1);
opacity: 1;
}
.dropdown li > a {
padding: 6px 8px;
display: flex;
transition: 0.5s;
flex-direction: column;
border-radius: 4px;
white-space: nowrap;
}
.dropdown li > a:hover {
background-color: #cccccc;
transition: 0.5s;
}
JavaScript
let buttonIdCounter = 0;
const dropdowns = document.querySelectorAll('.dropdown');
dropdowns.forEach((dropdown) => {
const button = dropdown.querySelector('a[data-toggle="dropdown"]');
const menu = dropdown.querySelector('.dropdown-menu');
const buttonId = `dropdown-button-${buttonIdCounter}`;
const menuId = `dropdown-menu-${buttonIdCounter}`;
buttonIdCounter++;
button.dataset.buttonId = buttonId;
menu.dataset.menuId = buttonId;
});
document.addEventListener('click', (event) => {
const clickedButton = event.target.closest('a[data-toggle="dropdown"]');
const openMenus = document.querySelectorAll('.dropdown-menu.show');
openMenus.forEach(menu => {
const menuId = menu.dataset.menuId;
const relatedButton = document.querySelector(`a[data-button-id="${menuId}"]`);
const arrow = relatedButton?.querySelector('.icon-arrow');
if (arrow) {
arrow.style.transform = "rotate(0)";
}
menu.classList.remove('show');
});
if (!clickedButton) return;
const buttonId = clickedButton.dataset.buttonId;
const relatedMenu = document.querySelector(`.dropdown-menu[data-menu-id="${buttonId}"]`);
const arrow = clickedButton.querySelector('.icon-arrow');
if (relatedMenu) {
const isMenuOpen = relatedMenu.classList.toggle('show');
if (arrow) {
arrow.style.transform = isMenuOpen ? "rotate(180deg)" : "rotate(0)";
}
}
event.preventDefault();
});
document.addEventListener('click', (event) => {
if (!event.target.closest('.dropdown')) {
const openMenus = document.querySelectorAll('.dropdown-menu.show');
openMenus.forEach(menu => {
const menuId = menu.dataset.menuId;
const relatedButton = document.querySelector(`a[data-button-id="${menuId}"]`);
const arrow = relatedButton?.querySelector('.icon-arrow');
...