Accordion menu designed exclusively with JavaScript

Implementation of required menu structure:

  • Main Menu
    • Submenu
      • Contacts
      • News
      • Photo
    • Submenu
    • Submenu
    • Submenu
  • Main Menu
  • Main Menu
  • Main Menu

When clicking on the "Main Menu" button, a list of "Submenu" elements opens. Clicking on the "Submenu" button opens a list of menu links. The objective is to close all other "Main Menu" buttons when pressing one, and to close all other "Submenu" buttons when clicking on one.

Code Sample:

<https://codepen.io/artemkhmyrov/pen/oNMgGpd>

I have successfully implemented the functionality for the first level of the menu. When I click on a "Main Menu" button, it opens the corresponding "Submenu", and clicking on another "Main Menu" button closes the previous one. However, when clicking on a "Submenu", everything closes.

Answer №1

If you're looking to implement a multilevel menu, you can utilize the following approach:

document.querySelector(".burger-menu__icon").addEventListener("click", function () {
  document.querySelector('.burger-menu__box').style.top="2%";
  document.querySelector('.burger-menu__box').style.right = "51%";
  });

   
  const burgerMenu = document.querySelector(".burger-menu");
  const burgerMenuIcon = document.querySelector(".burger-menu__icon");
  const burgerMenuBox = document.querySelector(".burger-menu__box");
  const container = burgerMenuBox.querySelector(".container");
  const burgerMenuSub = container.querySelector(".burger-menu-sub");
  let burgerMenuTitle = burgerMenuSub.querySelectorAll(".burger-menu-title");
  let burgerMenuContent = burgerMenuSub.querySelectorAll(".burger-menu-content");

  

for (let i = 0; i < burgerMenuTitle.length; i++) {
  burgerMenuTitle[i].addEventListener("click", (e) => {
    var menu1 = document.getElementsByClassName('menu1');
    for (var j = 0; j < menu1.length; j ++) {
      menu1[j].style.display="none";
    }
    burgerMenuContent[i].classList.toggle("burger-menu-content");
    burgerMenuContent[i].style.display = "block";
  });
}
    *,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  font-size: 0.9944vw;
  font-style: normal;
  font-weight: normal;
  line-height: 1.2;
  margin: 0;
  padding: 0;
}

ul li {
  margin: 0;
  padding: 0;
  list-style: none;
}

.container {
  width: 129.4rem;
  margin: 0 auto;
}

.header .container {
  display: flex;
}
.header__top {
  background-color: rgb(166, 170, 166);
  margin-bottom: 1.7rem;
}
.header__top .container {
  justify-content: space-between;
  align-items: center;
  height: 3.6rem;
}

.burger-icon {
  display: flex;
  width: 2.55rem;
  align-items: center;
  height: 2rem;
  justify-content: center;
  
}
.burger-icon.active::after {
  transition: all 0.9s ease 0s;
  transform: rotate(-225deg);
}
.burger-icon.active::before {
  transition: all 0.9s ease 0s;
  transform: rotate(225deg);
}
.burger-icon::after {
  transform: rotate(90deg);
}
.burger-icon::before,
.burger-icon::after {
  position: absolute;
  content: "";
  background-color: white;
  width: 0.2rem;
  height: 1.1rem;
}

.burger-menu {
  width: 3rem;
}
.burger-menu__icon {
  z-index: 15;
  display: block;
  position: relative;
  width: 2rem;
  height: 1.4rem;
  cursor: pointer;
  background: #4862b6;
}
.burger-menu__icon span,
.burger-menu__icon:before,
.burger-menu__icon:after {
  left: 0;
  position: absolute;
  height: 15%;
  width: 100%;
  transition: all 0.3s ease 0s;
  background-color: #fff;
  border-radius: 2rem;
}
.burger-menu__icon::before,
.burger-menu__icon::after {
  content: "";
}
.burger-menu__icon::before {
  top: 0;
}
.burger-menu__icon::after {
  bottom: 0;
}
.burger-menu__icon span {
  top: 50%;
  transform: scale(1) translate(0, -50%);
}
.burger-menu__icon._active span {
  transform: scale(0) translate(0, -50%);
}
.burger-menu__icon._active:before {
  top: 50%;
  transform: rotate(-45deg) translate(0, -50%);
}
.burger-menu__icon._active:after {
  bottom: 50%;
  transform: rotate(45deg) translate(0, 50%);
}
.burger-menu__box {
  position: absolute;
  top: -100%;
  right: 50%;
  transform: translate(50%, 0);
  min-height: 31rem;
  background-color: rgb(180, 180, 180);
  padding-top: 5rem;
  transition: all 0.3s ease 0s;
  z-index: 11;
  border-radius: 0 0 1.5rem 1.5rem;
}
.burger-menu__box .container {
  justify-content: center;
  color: white;
  font-size: 5rem;
  align-items: center;
  height: 100%;
  font-weight: bold;
}
.burger-menu__box._active {
  top: 0;
}
.burger-menu-content {
  margin-left: 2.4rem;
  display: none;
  right: 20%;
}
.burger-menu-content-open {
  display: block;
}
.burger-menu-title {
  padding: 1.1rem 0rem;
  display: flex;
  font-weight: 400;
  font-size: 1.6rem;
  line-height: 1.9rem;
  color: #ffffff;
}
.burger-menu-title:hover {
  cursor: pointer;
}
.burger-menu-title:hover > .burger-icon::before,
.burger-menu-title:hover > .burger-icon::after {
  color: #4862b6;
}
.burger-menu-title:hover a {
  color: #4862b6;
}
.burger-menu-sub {
  width: 100%;
  display: flex;
  flex-direction: row;
  height: 100%;
  justify-content: space-around;
}
.burger-menu__section-wrap-link {
  padding: 0rem 0rem 0.9rem 3rem;
  line-height: 1.2rem;
}
.burger-menu__section-link {
  font-weight: 400;
  font-size: 1.6rem;
  color: #ffffff;
}
.burger-menu__section-link::before {
  content: "";
  position: absolute;
  border-top: 0.3rem solid transparent;
  border-left: 0.4rem solid #fff;
  border-bottom: 0.3rem solid transparent;
  margin-left: -1rem;
  margin-top: 1.6rem;
}
.burger-menu__section-link:hover::before {
  border-left: 0.4rem solid #4862b6;
}
.burger-menu__section-links {
  font-weight: 400;
  font-size: 1rem;
}
.burger-menu__sub-sub-link {
  padding: 0rem 0rem 0.9rem 0rem;
  font-weight: 400;
  font-size: 1.6rem;
  line-height: 1.9rem;
  color: #ffffff;
}
.burger-menu__sub-sub-title {
  pointer-events: none;
  padding: 0rem 0rem 0.9rem 0rem;
  font-weight: 400;
  font-size: 1.6rem;
  line-height: 1.9rem;
  color: #ffffff;
}
.burger-menu__sub-item {
  width: 25rem;
}
.burger-menu-list {
  width: 28.5rem;
}
.burger-menu__wrap-accordion {
  padding: 0rem 0rem 2.5rem 2.5rem;
  overflow-y: scroll;
  display: flex;
  max-height: 115rem;
  width: 100%;
  flex-direction: row;
}
.burger-menu__wrap-accordion::-webkit-scrollbar {
  width: 0.001rem;
  background: green;
}
.burger-menu__wrap-item {
  padding: 1rem 0rem;
  display: flex;
  width: 100%;
}
<body>


<div class="burger-menu__icon">
  <span></span>
</div>

<div class="burger-menu__box">
  <div class="container">
    <nav class="burger-menu-sub menu">

      <div class="burger-menu__wrap-accordion">
        <ul class="burger-menu-list">
          <ul class="burger-menu-list">
            <li class="burger-menu__item">
            <li class="burger-menu-title">
              <div class="burger-icon"></div>
              <a href="#" class="burger-menu__sub-sub-link">Menu</a>
            </li>
            <ul class="burger-menu-content">
              <li class="burger-menu__sub-item">
                  <li class="burger-menu-title">
                    <div class="burger-icon"></div>
                    <a href="#" class="burger-menu__sub-sub-link">Sub Menu</a>
                  </li>
                  <ul class="burger-menu-content menu1">
                    <li class="burger-menu__section-wrap-link">
                      <a href="#" class="burger-menu__section-link">Paragraph 1</a>
                    </li>
                    <li class="burger-menu__section-wrap-link">
                      <a href="#" class="burger-menu__section-link">Paragraph 2</a>
                    </li>
                    <li class="burger-menu__section-wrap-link">
                      <a href="#" class="burger-menu__section-link">Paragraph 3</a>
                    </li>
                  </ul>
              </li>
              <li class="burger-menu__sub-item">
                  <li class="burger-menu-title">
                    <div class="burger-icon"></div>
                    <a href="#" class="burger-menu__sub-sub-link">Sub Menu</a>
                  </li>
                  <ul class="burger-menu-content menu1">
                    <li class="burger-menu__section-wrap-link">
                      <a href="#" class="burger-menu__section-link">Paragraph 1</a>
                    </li>
                    <li class="burger-menu__section-wrap-link">
                      <a href="#" class="burger-menu__section-link">Paragraph 2</a>
                    </li>
                    <li class="burger-menu__section-wrap-link">
                      <a href="#" class="burger-menu__section-link">Paragraph 3</a>
                    </li>
                  </ul>
              </li>
              <li class="burger-menu__sub-item">
                  <li class="burger-menu-title">
                    <div class="burger-icon"></div>
                    <a href="#" class="burger-menu__sub-sub-link">Sub Menu</a>
                  </li>
                  <ul class="burger-menu-content menu1">
                    <li class="burger-menu__section-wrap-link">
                      <a href="#" class="burger-menu__section-link">Paragraph 1</a>
                    </li>
                    <li class="burger-menu__section-wrap-link">
                      <a href="#" class="burger-menu__section-link">Paragraph 2</a>
                    </li>
                    <li class="burger-menu__section-wrap-link">
                      <a href="#" class="burger-menu__section-link">Paragraph 3</a>
                    </li>
                  </ul>
              </li>
            </ul>
            </li>
          </ul>

          <ul class="burger-menu-list">
            <li class="burger-menu__item">
            <li class="burger-menu-title">
              <div class="burger-icon"></div>
              <a href="#" class="burger-menu__sub-sub-link">Menu</a>
            </li>
            <ul class="burger-menu-content">
              <li class="burger-menu__sub-item">
              <li class="burger-menu-title">
                <div class="burger-icon"></div>
                <a href="#" class="burger-menu__sub-sub-link">Sub Menu</a>
              </li>
              <ul class="burger-menu-content menu1">
                <li class="burger-menu__section-wrap-link">
                  <a href="#" class="burger-menu__section-link">Paragraph 1</a>
                </li>
                <li class="burger-menu__section-wrap-link">
                  <a href="#" class="burger-menu__section-link">Paragraph 2</a>
                </li>
                <li class="burger-menu__section-wrap-link">
                  <a href="#" class="burger-menu__section-link">Paragraph 3</a>
                </li>
              </ul>
              </li>
              <li class="burger-menu__sub-item">
              <li class="burger-menu-title">
                <div class="burger-icon"></div>
                <a href="#" class="burger-menu__sub-sub-link">Sub Menu</a>
              </li>
              <ul class="burger-menu-content menu1">
                <li class="burger-menu__section-wrap-link">
                  <a href="#" class="burger-menu__section-link">Paragraph 1</a>
                </li>
                <li class="burger-menu__section-wrap-link">
                  <a href="#" class="burger-menu__section-link">Paragraph 2</a>
                </li>
                <li class="burger-menu__section-wrap-link">
                  <a href="#" class="burger-menu__section-link">Paragraph 3</a>
                </li>
              </ul>
              </li>
              <li class="burger-menu__sub-item">
              <li class="burger-menu-title">
                <div class="burger-icon"></div>
                <a href="#" class="burger-menu__sub-sub-link">Sub Menu</a>
              </li>
              <ul class="burger-menu-content menu1">
                <li class="burger-menu__section-wrap-link">
                  <a href="#" class="burger-menu__section-link">Paragraph 1</a>
                </li>
                <li class="burger-menu__section-wrap-link">
                  <a href="#" class="burger-menu__section-link">Paragraph 2</a>
                </li>
                <li class="burger-menu__section-wrap-link">
                  <a href="#" class="burger-menu__section-link">Paragraph 3</a>
                </li>
              </ul>
              </li>
            </ul>
            </li>
          </ul>
        </ul>

         
      </div>
    </nav>
  </div>
</div>
       

</body>

Answer №2

To optimize your website layout, my recommendation is to start with restructuring the HTML code.

<ul>
    <li>
      <a>Home</a>
         <ul>
             <li>
                 <a>About Us</a>
                   <ul>
                      <li>Team</li>
                      <li>Mission</li>
                      <li>Vision</li>
                   </ul>
             </li>
             <li>Services</li>
             <li>Products</li>
          </ul>
    </li>
    <li>
       <a>Contact</a>
    </li>
     /*-- continue this structure --*/
</ul>

After organizing the HTML elements, you can utilize JavaScript to expand specific <li> items as needed.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What should be transmitted to the front-end following the successful validation of a token on the server?

My process starts with a login page and then moves to the profile page. When it comes to handling the token on the backend, I use the following code: app.use(verifyToken); function verifyToken(req, res, next) { if (req.path === '/auth/google&ap ...

How can we redirect to the current page in JavaScript while passing an additional variable?

How can I capture the current URL and add "&p=1" to it before redirecting? Looking for a solution! ...

Placing one text above another text

I recently came across a unique font that requires both fill and shadow to be used together, with the fill on top and the shadow underneath. I managed to layer them successfully using relative and absolute positioning, as shown in this example. Here is ho ...

Discovering the quantity of identical elements within a JavaScript array

Looking for some assistance in solving a JavaScript problem as I am relatively new to the language: I have an array and I need help in determining the count of identical values. Below is my array: var arr = ["red", "blue", "green", "red", "red", "gray"] ...

Using functions like nl2br() for new line breaks, preg_replace for replacing patterns, htmlspecialchars() for encoding special

I've reviewed all the answers on this topic, but I'm still struggling to find the correct method for sanitizing data. My task is to enter: <?php echo 'yes'; ?> <?php echo 'yes' ?> into a text area, submit it in ...

Container Slides Along Despite Accurate Measurements

In a recent project of mine, I utilized two containers positioned side by side. Upon clicking a button, my goal was to have the content container (essentially a false body) decrease its width while the menu container would slide in. Despite my best effort ...

Looking to learn how to replicate data effortlessly with either javascript or jquery?

I am currently trying to figure out how close I am to successfully cloning this div. Honestly, I am a bit lost at this point and could really use some assistance. Should I consider using jQuery for this task? <div id="question20">20. Details of Chi ...

Node.js Express post query failing to set content type

I have a POST request implemented with the express framework to submit a query to a rest api. Here is the relevant code snippet: var request = require('request'); app.post('/compute', function(req, postResponse) { var queryJSON = re ...

Is there a way to update a useState in TabPanel without causing a re-render?

For the past few months, I've been immersing myself in React and MUI. Recently, I encountered a problem that has me stumped. The Goal: I receive data from a backend and need to display it for users to edit before sending the changes back to the serv ...

Is it Possible to Load Images Without Using Javascript?

When I hover over certain links on my HTML pages, large images are displayed but take a while to load. I prefer not to use JavaScript to preload the images. Are there any alternative solutions available? ...

Updating subdata in an array using Reactjs handleChange

I am facing an issue with my handleChange function. While I can easily change data in the same directory without any problem, I'm struggling to update sub-data. I would like to find a clean solution for this without having to add extra functions withi ...

angularJS transformRequest for a specified API call

Looking for a way to pass multipart/formdata through a $resource in Angular so I can post an image. I discovered a helpful solution on this Stack Overflow thread. However, the solution applies to all requests within my modules, and I only want it to apply ...

Exploring the implementation of method decorators that instantiate objects within Typescript

Currently, I have been working on a lambda project and utilizing the lambda-api package for development. As part of this process, I have implemented decorators named Get and Post to facilitate mapping routes within the lambda api object. These decorators e ...

Attempting to conceal my default drop-down menu

I need to find a way to hide my drop down menu by default, as it currently shows up automatically. The drop down menu in question is under "My Account". This is the HTML code I'm working with: <li class="hoverli"> <a href="/customer/ac ...

What is the method for incorporating an upward arrow into a select element, while also including a downward arrow, in order to navigate through options exclusively with

I have a select element that I have styled with up and down arrows. However, I am seeking assistance to navigate the options dropdown solely using these arrows and hide the dropdown list. Here is the HTML: <div class="select_wrap"> <d ...

Bootstrap struggles to create panels of uniform size

Here is the code snippet I am currently working with: <div class="col-md-4"> <div class="panel panel-default"> <div class="panel-heading"> <h4><i class="fa fa-fw fa-tasks"></i> Extreme Performance</ ...

Obtain specific fields from a multidimensional array object using lodash

My dilemma involves working with an object that has the following structure: var data = [ { "inputDate":"2017-11-25T00:00:00.000Z", "billingCycle":6, "total":1 },{ "inputDate":"2017-11-28T00:00:00.000Z", "bi ...

Issue with Abide Validation Events not triggering in Reveal Modal for Foundation Form

Currently, I am developing a login/registration feature for a basic web application using Foundation. On the index page, users are presented with a login screen and a register button. When the user clicks on the register button, a Reveal Modal pops up cont ...

Do you think there is a more efficient way to solve this issue?

const [active, setActive] = React.useState(["active", "", "", "", ""]);``your unique text`` const hrefs = React.useMemo( () => ["/", "/about", "/skills", "/projects", "/contact"], [] ); React.useEffect(() => { setInterval(() => { ...

Error alert: Conversion issue encountered when trying to output a singular variable as a string from

Encountered a peculiar error while attempting to display a single variable retrieved from the database. The process involves querying the top ID from the database and storing it in a variable. The code snippet looks like this: $ID_Query = "SELECT DIS ...