Julie R
Julie R

Reputation: 37

Slide our menu - Make submenu the same level as parent

I'm creating slide-out multilevel menu and I don't know how to make submenu slider the same level as the parent menu. When parent item located on second, third and other levels and I'm opening submenu - submenu appears on the same level as parent item. But I would like to have submenu full height and starts from the very top. I have now this: enter image description here

And would like to have this:

enter image description here

here is my code:

document.addEventListener("DOMContentLoaded", function() {
  const hamburgerMenu = document.querySelector('.hamburger-menu');
  const mainMenu = document.querySelector('.main-menu');
  const menuContainer = document.querySelector('.menu-container'); // Add this line

  hamburgerMenu.addEventListener('click', () => {
    mainMenu.style.left = mainMenu.style.left === '0px' ? '-250px' : '0px';
  });

  const submenuItems = document.querySelectorAll('.has-submenu');

  submenuItems.forEach(item => {
    item.addEventListener('click', (event) => {
      event.stopPropagation();
      if (!item.classList.contains('open')) {
        closeSubmenus();
      }
      item.classList.toggle('open');
    });
  });

  function closeSubmenus() {
    submenuItems.forEach(item => {
      item.classList.remove('open');
    });
  }

  // Close submenu when clicking outside
  document.addEventListener('click', (event) => {
    if (!menuContainer.contains(event.target) && mainMenu.style.left === '0px') {
      closeSubmenus();
      mainMenu.style.left = '-250px'; // Close the menu
    }
  });
});
/* Your CSS styles here */

/* Hamburger menu icon styling */
.hamburger-menu {
  cursor: pointer;
}

.bar {
  display: block;
  width: 25px;
  height: 3px;
  margin: 5px 0;
  background-color: #333;
}

/* Main menu styling */
.menu-container {
  position: relative;
}

.main-menu {
  list-style: none;
  padding: 0;
  position: absolute;
  top: 50px; /* Adjust this according to your layout */
  left: -250px; /* Initial position outside the viewport */
  width: 250px;
  background-color: #fff;
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
  transition: left 0.3s ease;
    height: 100vh;
}

.main-menu li {
  padding: 10px;
  border-bottom: 1px solid #ddd;
  position: relative;
}

/* Submenu styling */
.submenu {
  display: none;
  position: absolute;
  top: 0;
  left: 100%; /* Position next to the parent menu */
  width: 250px;
  background-color: #f9f9f9;
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
  transition: opacity 0.3s ease;
}

/* Display submenu on click */
.has-submenu.open .submenu {
  display: block;
  opacity: 1;
}
<div class="menu-container">
  <div class="hamburger-menu">
    <span class="bar"></span>
    <span class="bar"></span>
    <span class="bar"></span>
  </div>
  <ul class="main-menu">
    <li><a href="#">Home</a></li>
    <li class="has-submenu">
      <a href="#">Services</a>
      <ul class="submenu">
        <li><a href="#">Service 1</a></li>
        <li><a href="#">Service 2</a></li>
      </ul>
    </li>
    <li class="has-submenu">
      <a href="#">About</a>
      <ul class="submenu">
        <li><a href="#">About 1</a></li>
        <li><a href="#">About 2</a></li>
      </ul>
    </li>
  </ul>
</div>

Upvotes: 0

Views: 62

Answers (2)

OldPadawan
OldPadawan

Reputation: 1251

submenu appears on the same level as parent item.

it's what you ask when using the following css property:

.main-menu li {
  padding: 10px;
  border-bottom: 1px solid #ddd;
  position: relative;
}

But I would like to have submenu full height and starts from the very top.

get rid of this part:

position: relative;

From web docs:

relative: The element is positioned according to the normal flow of the document, and then offset relative to itself based on the values of top, right, bottom, and left. The offset does not affect the position of any other elements; thus, the space given for the element in the page layout is the same as if position were static.

document.addEventListener("DOMContentLoaded", function() {
  const hamburgerMenu = document.querySelector('.hamburger-menu');
  const mainMenu = document.querySelector('.main-menu');
  const menuContainer = document.querySelector('.menu-container'); // Add this line

  hamburgerMenu.addEventListener('click', () => {
    mainMenu.style.left = mainMenu.style.left === '0px' ? '-250px' : '0px';
  });

  const submenuItems = document.querySelectorAll('.has-submenu');

  submenuItems.forEach(item => {
    item.addEventListener('click', (event) => {
      event.stopPropagation();
      if (!item.classList.contains('open')) {
        closeSubmenus();
      }
      item.classList.toggle('open');
    });
  });

  function closeSubmenus() {
    submenuItems.forEach(item => {
      item.classList.remove('open');
    });
  }

  // Close submenu when clicking outside
  document.addEventListener('click', (event) => {
    if (!menuContainer.contains(event.target) && mainMenu.style.left === '0px') {
      closeSubmenus();
      mainMenu.style.left = '-250px'; // Close the menu
    }
  });
});
/* Your CSS styles here */

/* Hamburger menu icon styling */
.hamburger-menu {
  cursor: pointer;
}

.bar {
  display: block;
  width: 25px;
  height: 3px;
  margin: 5px 0;
  background-color: #333;
}

/* Main menu styling */
.menu-container {
  position: relative;
}

.main-menu {
  list-style: none;
  padding: 0;
  position: absolute;
  top: 50px; /* Adjust this according to your layout */
  left: -250px; /* Initial position outside the viewport */
  width: 250px;
  background-color: #fff;
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
  transition: left 0.3s ease;
    height: 100vh;
}

.main-menu li {
  padding: 10px;
  border-bottom: 1px solid #ddd;
}

/* Submenu styling */
.submenu {
  display: none;
  position: absolute;
  top: 0;
  left: 100%; /* Position next to the parent menu */
  width: 250px;
  background-color: #f9f9f9;
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
  transition: opacity 0.3s ease;
}

/* Display submenu on click */
.has-submenu.open .submenu {
  display: block;
  opacity: 1;
}
<div class="menu-container">
  <div class="hamburger-menu">
    <span class="bar"></span>
    <span class="bar"></span>
    <span class="bar"></span>
  </div>
  <ul class="main-menu">
    <li><a href="#">Home</a></li>
    <li class="has-submenu">
      <a href="#">Services</a>
      <ul class="submenu">
        <li><a href="#">Service 1</a></li>
        <li><a href="#">Service 2</a></li>
      </ul>
    </li>
    <li class="has-submenu">
      <a href="#">About</a>
      <ul class="submenu">
        <li><a href="#">About 1</a></li>
        <li><a href="#">About 2</a></li>
      </ul>
    </li>
  </ul>
</div>

Upvotes: 1

twalow
twalow

Reputation: 760

Update this:

.main-menu li {
    padding: 10px;
    border-bottom: 1px solid #ddd;
    /* remove the position relative on this element */
}

Upvotes: 2

Related Questions