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');
 ...