Search code examples
javascriptaccessibility

How do I trap focus within a panel with Vanilla javascript?


I am trying to create an accessible navigation menu and I want to trap the focus within each panel. When I click on the hamburger button, it will open the panel displaying a list of buttons or links. I want to be able to tab/up&down arrow through the options and have it loop again based on whether its the first or last focusable element.

If it's just one level of navigation links, I know I can get all of the focusable elements and identify the first and last sibling and add an event listener keydown to loop, but my problem is that these navigation links have sub levels and I'm not really sure how to approach it.

In my codepen, I made a function where I get the id of the panel and get the array of the focusable elements and set it in a map. I'm not sure if that's the right approach because my thought was to identify which panel is currently active then get the array of focusable elements from the map, find the first/last focusable element, then add the eventlistener to check what element is being focused until it finds the first or last and then loops. But when I was coding it, it just didn't feel right at all.

const navigation = document.getElementsByClassName("n-navigation")[0];
const navigationMobile= navigation.getElementsByClassName("n-navigation__mobile")[0];
const navigationBlur= navigation.getElementsByClassName("n-navigation__blur")[0];

const hamburgerMenuBtn = navigation.firstElementChild;
hamburgerMenuBtn.addEventListener("click", openHamburgerMenu);

const mainContainer = navigationMobile.firstElementChild;
mainContainer.id = "main-container";
const closeMenuBtn = mainContainer.firstElementChild;
closeMenuBtn.addEventListener("click", closeMenu);
const mainList = mainContainer.getElementsByTagName("ul")[0];

const triggers = mainList.querySelectorAll("button.n-navigation__mobile__mainContainer__mainList__trigger, button.n-navigation__mobile__mainContainer__mainList__panel__subContainer__subList__trigger");
const previousBtns = mainList.querySelectorAll("button.n-navigation__mobile__mainContainer__mainList__panel__subContainer__previous, button.n-navigation__mobile__mainContainer__mainList__panel__subContainer__subList__panel__container__previous");

let activePanel;
let activeContainer;

let focusableMap = new Map();

for (let a=0; a < triggers.length; a++) {
  triggers[a].id = "trigger-id-" + a;
  triggers[a].addEventListener("click", nextTopic);
  
  let panel = triggers[a].nextElementSibling;
  panel.id = "panel-id-" + a;
  
  triggers[a].setAttribute("aria-controls", panel.id);
}
for (let a=0; a < previousBtns.length; a++) {
  previousBtns[a].addEventListener("click", previousTopic);
}

function openHamburgerMenu() {
  navigation.classList.add("n-navigation--active");
  navigationBlur.classList.remove("n-navigation__blur--hide");
  navigationBlur.classList.add("n-navigation__blur--show");
  this.setAttribute("aria-expanded", "true");
  
  if (!focusableMap.has(mainContainer.id)) {
    let container = mainContainer.getAttribute('class');
    addFocusableToMap(mainContainer, container);
  }
}

function closeMenu() {
  navigation.classList.remove("n-navigation--active");
  navigationBlur.classList.remove("n-navigation__blur--show");
  navigationBlur.classList.add("n-navigation__blur--hide");
  hamburgerMenuBtn.setAttribute("aria-expanded", "false");
}

function nextTopic() {
  console.log("next topic");
  
  let panel = this.nextElementSibling;
  let container = panel.firstElementChild.getAttribute('class');
  if (!focusableMap.has(panel.id)) addFocusableToMap(panel, container);
  
  if (this.classList.contains("n-navigation__mobile__mainContainer__mainList__trigger")) {
    mainList.parentElement.classList.add("n-navigation__mobile__mainContainer--right");
    panel.classList.add("n-navigation__mobile__mainContainer__mainList__panel--active");
  } else {
    activeContainer = activePanel;
    activePanel.classList.add("n-navigation__mobile__mainContainer__mainList__panel--right");
    panel.classList.add("n-navigation__mobile__mainContainer__mainList__panel__subContainer__subList__panel--active");
  }
  activePanel = panel;

}

function previousTopic() {
  console.log("previous topic");
  
  if (this.classList.contains("n-navigation__mobile__mainContainer__mainList__panel__subContainer__previous")) {
    mainList.parentElement.classList.remove("n-navigation__mobile__mainContainer--right");
    activePanel.classList.remove("n-navigation__mobile__mainContainer__mainList__panel--active");
    activePanel = null;  
  } else {
    activeContainer.classList.remove("n-navigation__mobile__mainContainer__mainList__panel--right");
    activePanel.classList.remove("n-navigation__mobile__mainContainer__mainList__panel__subContainer__subList__panel--active");
    activePanel = activeContainer;
    activeContainer = null;
  }
}

function addFocusableToMap(panel, container) {
  const focusable = panel.querySelectorAll("." + container + " > button, ." + container + " > ul > li > button, ." + container + " > ul > li > a");
  const newFocusable = [];
  
  for (let a=0; a < focusable.length; a++) {
    focusable[a].dataset.triggerid = panel.id;
    newFocusable.push(focusable[a]);
  }
  focusableMap.set(panel.id, focusable);

}
body {
  margin: 0;
}

.n-navigation {
  display: grid;
  height: 4.375em;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  padding: 1em;
  background-color: #f7f9fa;
}
@media screen and (min-width: 50em) {
  .n-navigation__hamburgerMenu {
    display: none;
  }
}
.n-navigation__logo {
  text-align: center;
}
@media screen and (min-width: 50em) {
  .n-navigation__logo {
    text-align: left;
  }
}
.n-navigation__mobile {
  height: 100vh;
  width: 20em;
  background-color: white;
  position: absolute;
  top: 0;
  left: 0;
  overflow: hidden;
  transform: translateX(-20em);
  visibility: hidden;
  z-index: 0;
  transition: transform 350ms, z-index 0s, visibility 0s;
  transition-delay: 0s, 350ms, 350ms;
}
@media screen and (min-width: 50em) {
  .n-navigation__mobile {
    display: none;
  }
}
.n-navigation__mobile__mainContainer {
  padding: 1.375em 1.5em;
  transform: translateX(0);
  transition: transform 350ms;
  visibility: visible;
}
.n-navigation__mobile__mainContainer ul {
  list-style-type: none;
  padding-left: 0;
}
.n-navigation__mobile__mainContainer__close {
  display: block;
  margin-left: auto;
}
.n-navigation__mobile__mainContainer__mainList {
  margin-top: 2.25em;
  margin-bottom: 3em;
}
.n-navigation__mobile__mainContainer__mainList__trigger {
  display: flex;
  width: 100%;
  background-color: transparent;
  color: #1d1d1f;
  text-decoration: none;
  border: none;
  padding: 0.5em 0;
  justify-content: space-between;
  align-items: center;
}
.n-navigation__mobile__mainContainer__mainList__trigger:hover, .n-navigation__mobile__mainContainer__mainList__trigger:focus {
  cursor: pointer;
}
.n-navigation__mobile__mainContainer__mainList__trigger:hover .n-navigation__mobile__mainContainer__mainList__trigger__icon, .n-navigation__mobile__mainContainer__mainList__trigger:focus .n-navigation__mobile__mainContainer__mainList__trigger__icon {
  color: #c41320;
}
.n-navigation__mobile__mainContainer__mainList__trigger__copy {
  font-family: tahoma;
  font-size: 1.625rem;
}
.n-navigation__mobile__mainContainer__mainList__trigger__icon {
  font-size: 1.5em;
  transition: color 350ms;
}
.n-navigation__mobile__mainContainer__mainList__panel {
  width: 100%;
  position: absolute;
  top: 0;
  left: 0;
  transform: translateX(-20em);
  transition: transform 350ms;
  visibility: hidden;
  transition: transform 350ms, visibility 0s;
  transition-delay: 0s, 350ms;
}
.n-navigation__mobile__mainContainer__mainList__panel__subContainer {
  padding: 3em 1.5em;
}
.n-navigation__mobile__mainContainer__mainList__panel__subContainer__subList__panel {
  width: 100%;
  position: absolute;
  top: 0;
  left: 0;
  transform: translateX(-20em);
  visibility: hidden;
  transition: transform 350ms, visibility 0s;
  transition-delay: 0s, 350ms;
}
.n-navigation__mobile__mainContainer__mainList__panel__subContainer__subList__panel__container {
  padding: 3em 1.5em;
}
.n-navigation__mobile__mainContainer__mainList__panel__subContainer__subList__panel--active {
  visibility: visible;
  transition: transform 350ms, visibility 0s;
  transition-delay: 0s, 0s;
}
.n-navigation__mobile__mainContainer__mainList__panel__subContainer__subList__panel--right {
  transform: translateX(20em);
  visibility: hidden;
  transition: transform 350ms, visibility 0s;
  transition-delay: 0s, 350ms;
}
.n-navigation__mobile__mainContainer__mainList__panel--right {
  transform: translateX(0);
}
.n-navigation__mobile__mainContainer__mainList__panel--active {
  visibility: visible;
  transition: transform 350ms, visibility 0s;
  transition-delay: 0s, 0s;
}
.n-navigation__mobile__mainContainer--right {
  transform: translateX(20em);
  visibility: hidden;
  transition: transform 350ms, visibility 0s;
  transition-delay: 0s, 350ms;
}
.n-navigation__desktop {
  display: none;
}
@media screen and (min-width: 50em) {
  .n-navigation__desktop {
    display: block;
  }
}
.n-navigation__blur {
  display: block;
  position: fixed;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  background-color: rgba(18, 18, 18, 0.36);
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
}
.n-navigation__blur--hide {
  opacity: 0;
  visibility: hidden;
  z-index: -1;
  transition: opacity 450ms, visibility 0s, z-index 0s;
  transition-delay: 0s, 450ms, 450ms;
}
.n-navigation__blur--show {
  opacity: 1;
  visibility: visible;
  z-index: 0;
}
.n-navigation--active .n-navigation__mobile {
  transform: translateX(0);
  visibility: visible;
  z-index: 2;
  transition: transform 450ms, visibility 0s;
  transition-delay: 0s, 0s;
}
<nav class="n-navigation" role="navigation">
  <button class="n-navigation__hamburgerMenu" aria-label="Menu" aria-expanded="false">
     <svg aria-hidden="true" viewBox="0 0 24 24" role="img" width="24px" height="24px" fill="none">
       <path stroke="currentColor" stroke-width="1.5" d="M21 5.25H3M21 12H3m18 6.75H3"></path>
     </svg>
  </button>
  <div class="n-navigation__logo">
  <a href="#">Site Name</a>
  </div>
  
  <div class="n-navigation__mobile">
    <div class="n-navigation__mobile__mainContainer">
      <button class="n-navigation__mobile__mainContainer__close">X</button>
      <ul class="n-navigation__mobile__mainContainer__mainList">
        <li>
          <button class="n-navigation__mobile__mainContainer__mainList__trigger">
            <span class="n-navigation__mobile__mainContainer__mainList__trigger__copy">Menu Item 1</span>
            <span class="n-navigation__mobile__mainContainer__mainList__trigger__icon"> > </span>
          </button>
          <div class="n-navigation__mobile__mainContainer__mainList__panel">
            <div class="n-navigation__mobile__mainContainer__mainList__panel__subContainer">
              <button class="n-navigation__mobile__mainContainer__mainList__panel__subContainer__previous">All</button>
              <h2>Menu Item 1</h2>
              <ul class="n-navigation__mobile__mainContainer__mainList__panel__subContainer__subList">
                <li>
                  <a href="#" class="n-navigation__mobile__mainContainer__mainList__panel__subContainer__subList__trigger">
                    <span>Menu Item 1's</span>
                  </a>
                </li>
                <li>
                  <a href="#" class="n-navigation__mobile__mainContainer__mainList__panel__subContainer__subList__trigger">
                    <span>Menu Item 1's</span>
                  </a> 
                </li>
                <li>
                  <button class="n-navigation__mobile__mainContainer__mainList__panel__subContainer__subList__trigger">
                    <span>Menu Item 1's</span>
                    <span> > </span>
                  </button>
                  <div class="n-navigation__mobile__mainContainer__mainList__panel__subContainer__subList__panel">
                    <div class="n-navigation__mobile__mainContainer__mainList__panel__subContainer__subList__panel__container">
                      <button class="n-navigation__mobile__mainContainer__mainList__panel__subContainer__subList__panel__container__previous">Menu Item 1's</button>
                      <h3>Menu Item 1's</h3>
                      <ul>
                        <li>
                          <a href="#">HiM.\\</a>
                        </li>
                        <li>
                          <a href="#">Herrr</a>
                        </li>
                      </ul>
                    </div>
                  </div>
                </li>
              </ul>
            </div>
          </div>
        </li>
        <li>
          <button class="n-navigation__mobile__mainContainer__mainList__trigger">
            <span class="n-navigation__mobile__mainContainer__mainList__trigger__copy">Menu Item 2</span>
            <span class="n-navigation__mobile__mainContainer__mainList__trigger__icon"> > </s>
          </button>
          <div class="n-navigation__mobile__mainContainer__mainList__panel">
            <div class="n-navigation__mobile__mainContainer__mainList__panel__subContainer">
              <button class="n-navigation__mobile__mainContainer__mainList__panel__subContainer__previous">All</button>
              <h2>Menu Item 2</h2>
              <ul>
                <li>Menu Item 2's</li>
              </ul>
            </div>
          </div>
        </li>
        <li>
          <a href="#" class="n-navigation__mobile__mainContainer__mainList__trigger">
            <span class="n-navigation__mobile__mainContainer__mainList__trigger__copy">Menu Item 3</span>
          </a>
        </li>
      </ul>
    </div>
  </div>

  <div class="n-navigation__desktop"></div>
  <div class="n-navigation__iconMenu">
    search and cart
  </div>
  <div class="n-navigation__blur n-navigation__blur--hide"></div>
</nav>


Solution

  • I ended up having a map containing the panel.id and their array of focusableElements.

    When a panel is active, setFocusable(panel.id) will get the focusable array from the map and then it will set the global firstFocusableElement, lastFocusableElement based on the focusable array's first and last child.

    The focusable elements have the eventListener keyDownAction() which will check if it is using tab, arrow up, and arrow down. It will then check to see if those elements are either first or last and will shift its focus to the next focusable element.

    const navigation = document.getElementsByClassName("n-navigation")[0];
    const navigationMobile= navigation.getElementsByClassName("n-navigation__mobile")[0];
    const navigationBlur= navigation.getElementsByClassName("n-navigation__blur")[0];
    
    // Hamburger Menu Button
    const hamburgerMenuBtn = navigation.firstElementChild;
    hamburgerMenuBtn.addEventListener("click", openHamburgerMenu);
    
    // Main Container
    const mainContainer = navigationMobile.firstElementChild;
    mainContainer.id = "main-container";
    
    // Close Menu Buttom
    const closeMenuBtn = mainContainer.firstElementChild;
    closeMenuBtn.addEventListener("click", closeMenu);
    
    // Main Navigation Links
    const mainList = mainContainer.getElementsByTagName("ul")[0];
    
    // All Navigation Links that have Sub Links
    const triggers = mainList.querySelectorAll("button.n-navigation__mobile__mainContainer__mainList__trigger, button.n-navigation__mobile__mainContainer__mainList__panel__subContainer__subList__trigger");
    
    // Previous Buttons
    const previousBtns = mainList.querySelectorAll("button.n-navigation__mobile__mainContainer__mainList__panel__subContainer__previous, button.n-navigation__mobile__mainContainer__mainList__panel__subContainer__subList__panel__container__previous");
    
    // Check which panels are active
    let activePanel;
    
    // Previous active panels so when they want to go back a level, it pops
    let previous = [];
    
    // A map contains an array of keys with their complimentary array of focusable elements
    let focusableMap = new Map();
    
    // The current active variables to set to
    let focusablesActive;
    let firstFocusableElememt;
    let lastFocusableElement;
    let currentFocus = 0;
    
    // Loop through the triggers and add an eventListener to them to move to the next topic
    for (let a=0; a < triggers.length; a++) {
      triggers[a].id = "trigger-id-" + a;
      triggers[a].addEventListener("click", nextTopic);
      
      // Get the panel the trigger is associated to and give it an id.
      let panel = triggers[a].nextElementSibling;
      panel.id = "panel-id-" + a;
      
      // Add aria-controls with the panel id to trigger in order to show that the trigger controls that panel
      triggers[a].setAttribute("aria-controls", panel.id);
    }
    
    // Loop through the previous buttons and add an eventListener for them to move back to the previous topic
    for (let a=0; a < previousBtns.length; a++) {
      previousBtns[a].addEventListener("click", previousTopic);
    }
    
    // When the window is resized, it will close
    window.addEventListener("resize", closeMenu);
    
    
    
    // -- functions
    
    // Open Hamburger Menu
    function openHamburgerMenu() {
      // Add class to navigation to show that it is open
      navigation.classList.add("n-navigation--active");
      
      // Control blurring animation
      navigationBlur.classList.remove("n-navigation__blur--hide");
      navigationBlur.classList.add("n-navigation__blur--show");
      
      // Set Hamburger Menu aria-expanded to true
      this.setAttribute("aria-expanded", "true");
      
      let container = mainContainer.getAttribute('class');
      let focusables = getFocusableMap(mainContainer, container);
      
      // if the Main Container's id is not in the focusableMap then add it
      if (!focusableMap.has(mainContainer.id) && focusables.length > 0) {
        setFocusableMap(mainContainer, focusables);
      }
      
      activePanel = mainContainer;
      setFocusable(mainContainer.id);
    }
    
    function closeMenu() {
      navigation.classList.remove("n-navigation--active");
      navigationBlur.classList.remove("n-navigation__blur--show");
      navigationBlur.classList.add("n-navigation__blur--hide");
      hamburgerMenuBtn.setAttribute("aria-expanded", "false");
      
      activePanel = null;
      firstFocusableElement = null;
      lastFocusableElement = null;
      currentFocus = 0;
      
      hamburgerMenuBtn.focus();
    }
    
    function nextTopic() {
      console.log("next topic");
      
      let panel = this.nextElementSibling;
      let container = panel.firstElementChild.getAttribute('class');
      
      let focusables = getFocusableMap(panel, container);
      if (!focusableMap.has(panel.id) && focusables.length > 0) setFocusableMap(panel, focusables);
      
      if (previous.length == 0) {
        mainList.parentElement.classList.add("n-navigation__mobile__mainContainer--right");
        panel.classList.add("n-navigation__mobile__mainContainer__mainList__panel--active");
      } else {
        activePanel.classList.add("n-navigation__mobile__mainContainer__mainList__panel--right");
        panel.classList.add("n-navigation__mobile__mainContainer__mainList__panel__subContainer__subList__panel--active");
      }
      
      previous.push(activePanel);
      activePanel = panel;
      setFocusable(panel.id);
    }
    
    function previousTopic() {
      console.log("previous topic");
      
      let newActive = previous.pop();
      
      if (previous.length > 0) {
        newActive.classList.remove("n-navigation__mobile__mainContainer__mainList__panel--right");
        activePanel.classList.remove("n-navigation__mobile__mainContainer__mainList__panel__subContainer__subList__panel--active");
      } else {
        newActive.classList.remove("n-navigation__mobile__mainContainer--right");
        activePanel.classList.remove("n-navigation__mobile__mainContainer__mainList__panel--active");
      }
      
      activePanel = newActive;
      setFocusable(activePanel.id);
    }
    
    function getFocusableMap(panel, container) {
      const focusables = panel.querySelectorAll("." + container + " > button, ." + container + " > ul > li > button, ." + container + " > ul > li > a");
      return focusables;
    }
    
    function setFocusableMap(panel, focusables) {
      for (let a=0; a < focusables.length; a++) {
        focusables[a].dataset.triggerid = panel.id;
        focusables[a].addEventListener("keydown", keyboardAction);
      }
      focusableMap.set(panel.id, focusables);
    }
    
    function setFocusable(panelId) {
      console.log("setting");
      focusablesActive = focusableMap.get(panelId);
      firstFocusableElement = focusablesActive[0];
      lastFocusableElement = focusablesActive[focusablesActive.length - 1];
      
      currentFocus = 0;
      setTimeout(function() {
        firstFocusableElement.focus();
      }, 300);
    }
    
    function keyboardAction(e) {
      console.log("boop", e.key);
      
      switch (e.key) {
        case "ArrowUp":
          console.log("ArrowUp");
          currentFocus = currentFocus - 1;
          
          if (currentFocus < 0) {
            currentFocus = focusablesActive.length - 1;
            lastFocusableElement.focus();
          } else focusablesActive[currentFocus].focus();
          
          break;
        
        case "ArrowDown":
          console.log("ArrowDown");
          currentFocus = currentFocus + 1;
    
          if (currentFocus > focusablesActive.length - 1) {
            currentFocus = 0;
            firstFocusableElement.focus();
          } else focusablesActive[currentFocus].focus();
          
          break;
        
        case "Tab":
          e.preventDefault();
          break;
      }
      
    }
    body {
      margin: 0;
    }
    
    .n-navigation {
      display: grid;
      height: 4.375em;
      grid-template-columns: auto 1fr auto;
      align-items: center;
      padding: 1em;
      background-color: #f7f9fa;
    }
    @media screen and (min-width: 50em) {
      .n-navigation__hamburgerMenu {
        display: none;
      }
    }
    .n-navigation__logo {
      text-align: center;
    }
    @media screen and (min-width: 50em) {
      .n-navigation__logo {
        text-align: left;
      }
    }
    .n-navigation__mobile {
      height: 100vh;
      width: 20em;
      background-color: white;
      position: absolute;
      top: 0;
      left: 0;
      overflow: hidden;
      transform: translateX(-20em);
      visibility: hidden;
      z-index: 0;
      transition: transform 350ms, z-index 0s, visibility 0s;
      transition-delay: 0s, 350ms, 350ms;
    }
    @media screen and (min-width: 50em) {
      .n-navigation__mobile {
        display: none;
      }
    }
    .n-navigation__mobile__mainContainer {
      padding: 1.375em 1.5em;
      transform: translateX(0);
      transition: transform 350ms;
      visibility: visible;
    }
    .n-navigation__mobile__mainContainer ul {
      list-style-type: none;
      padding-left: 0;
    }
    .n-navigation__mobile__mainContainer__close {
      display: block;
      margin-left: auto;
    }
    .n-navigation__mobile__mainContainer__mainList {
      margin-top: 2.25em;
      margin-bottom: 3em;
    }
    .n-navigation__mobile__mainContainer__mainList__trigger {
      display: flex;
      width: 100%;
      background-color: transparent;
      color: #1d1d1f;
      text-decoration: none;
      border: none;
      padding: 0.5em 0;
      justify-content: space-between;
      align-items: center;
    }
    .n-navigation__mobile__mainContainer__mainList__trigger:hover, .n-navigation__mobile__mainContainer__mainList__trigger:focus {
      cursor: pointer;
    }
    .n-navigation__mobile__mainContainer__mainList__trigger:hover .n-navigation__mobile__mainContainer__mainList__trigger__icon, .n-navigation__mobile__mainContainer__mainList__trigger:focus .n-navigation__mobile__mainContainer__mainList__trigger__icon {
      color: #c41320;
    }
    .n-navigation__mobile__mainContainer__mainList__trigger__copy {
      font-family: tahoma;
      font-size: 1.625rem;
    }
    .n-navigation__mobile__mainContainer__mainList__trigger__icon {
      font-size: 1.5em;
      transition: color 350ms;
    }
    .n-navigation__mobile__mainContainer__mainList__panel {
      width: 100%;
      position: absolute;
      top: 0;
      left: 0;
      transform: translateX(-20em);
      transition: transform 350ms;
      visibility: hidden;
      transition: transform 350ms, visibility 0s;
      transition-delay: 0s, 350ms;
    }
    .n-navigation__mobile__mainContainer__mainList__panel__subContainer {
      padding: 3em 1.5em;
    }
    .n-navigation__mobile__mainContainer__mainList__panel__subContainer__subList__trigger {
      display: flex;
      width: 100%;
      background-color: transparent;
      color: #1d1d1f;
      text-decoration: none;
      border: none;
      padding: 12px 0;
      justify-content: space-between;
      align-items: center;
    }
    .n-navigation__mobile__mainContainer__mainList__panel__subContainer__subList__trigger:hover, .n-navigation__mobile__mainContainer__mainList__panel__subContainer__subList__trigger:focus {
      cursor: pointer;
    }
    .n-navigation__mobile__mainContainer__mainList__panel__subContainer__subList__trigger:hover .n-navigation__mobile__mainContainer__mainList__panel__subContainer__subList__trigger__icon, .n-navigation__mobile__mainContainer__mainList__panel__subContainer__subList__trigger:focus .n-navigation__mobile__mainContainer__mainList__panel__subContainer__subList__trigger__icon {
      color: #c41320;
    }
    .n-navigation__mobile__mainContainer__mainList__panel__subContainer__subList__trigger__copy {
      font-family: tahoma;
      font-size: 1rem;
    }
    .n-navigation__mobile__mainContainer__mainList__panel__subContainer__subList__trigger__icon {
      font-size: 1.25em;
      transition: color 350ms;
    }
    .n-navigation__mobile__mainContainer__mainList__panel__subContainer__subList__panel {
      width: 100%;
      position: absolute;
      top: 0;
      left: 0;
      transform: translateX(-20em);
      visibility: hidden;
      transition: transform 350ms, visibility 0s;
      transition-delay: 0s, 350ms;
    }
    .n-navigation__mobile__mainContainer__mainList__panel__subContainer__subList__panel__container {
      padding: 3em 1.5em;
    }
    .n-navigation__mobile__mainContainer__mainList__panel__subContainer__subList__panel--active {
      visibility: visible;
      transition: transform 350ms, visibility 0s;
      transition-delay: 0s, 0s;
    }
    .n-navigation__mobile__mainContainer__mainList__panel__subContainer__subList__panel--right {
      transform: translateX(20em);
      visibility: hidden;
      transition: transform 350ms, visibility 0s;
      transition-delay: 0s, 350ms;
    }
    .n-navigation__mobile__mainContainer__mainList__panel--right {
      transform: translateX(0);
    }
    .n-navigation__mobile__mainContainer__mainList__panel--active {
      visibility: visible;
      transition: transform 350ms, visibility 0s;
      transition-delay: 0s, 0s;
    }
    .n-navigation__mobile__mainContainer--right {
      transform: translateX(20em);
      visibility: hidden;
      transition: transform 350ms, visibility 0s;
      transition-delay: 0s, 350ms;
    }
    .n-navigation__desktop {
      display: none;
    }
    @media screen and (min-width: 50em) {
      .n-navigation__desktop {
        display: block;
      }
    }
    .n-navigation__blur {
      display: block;
      position: fixed;
      top: 0;
      bottom: 0;
      left: 0;
      right: 0;
      background-color: rgba(18, 18, 18, 0.36);
      -webkit-backdrop-filter: blur(4px);
      backdrop-filter: blur(4px);
    }
    .n-navigation__blur--hide {
      opacity: 0;
      visibility: hidden;
      z-index: -1;
      transition: opacity 450ms, visibility 0s, z-index 0s;
      transition-delay: 0s, 450ms, 450ms;
    }
    .n-navigation__blur--show {
      opacity: 1;
      visibility: visible;
      z-index: 0;
    }
    .n-navigation--active .n-navigation__mobile {
      transform: translateX(0);
      visibility: visible;
      z-index: 2;
      transition: transform 450ms, visibility 0s;
      transition-delay: 0s, 0s;
    }
    <nav class="n-navigation" role="navigation">
      <button class="n-navigation__hamburgerMenu" aria-label="Menu" aria-expanded="false" aria-controls="navigation-mobile-menu">
         <svg aria-hidden="true" viewBox="0 0 24 24" role="img" width="24px" height="24px" fill="none">
           <path stroke="currentColor" stroke-width="1.5" d="M21 5.25H3M21 12H3m18 6.75H3"></path>
         </svg>
      </button>
      <div class="n-navigation__logo">
      <a href="#">Site Name</a>
      </div>
      
      <div id="navigation-mobile-menu" class="n-navigation__mobile">
        <div class="n-navigation__mobile__mainContainer">
          <button class="n-navigation__mobile__mainContainer__close" aria-lable="Close Menu">X</button>
          <ul class="n-navigation__mobile__mainContainer__mainList">
            <li>
              <button class="n-navigation__mobile__mainContainer__mainList__trigger">
                <span class="n-navigation__mobile__mainContainer__mainList__trigger__copy">Menu Item 1</span>
                <span class="n-navigation__mobile__mainContainer__mainList__trigger__icon" aria-hidden="true"> > </span>
              </button>
              <div class="n-navigation__mobile__mainContainer__mainList__panel">
                <div class="n-navigation__mobile__mainContainer__mainList__panel__subContainer">
                  <button class="n-navigation__mobile__mainContainer__mainList__panel__subContainer__previous">All</button>
                  <h2>Menu Item 1</h2>
                  <ul class="n-navigation__mobile__mainContainer__mainList__panel__subContainer__subList">
                    <li>
                      <a href="#" class="n-navigation__mobile__mainContainer__mainList__panel__subContainer__subList__trigger">
                        <span class="n-navigation__mobile__mainContainer__mainList__panel__subContainer__subList__trigger__copy">
                          Menu Item 1's
                        </span>
                      </a>
                    </li>
                    <li>
                      <a href="#" class="n-navigation__mobile__mainContainer__mainList__panel__subContainer__subList__trigger">
                        <span class="n-navigation__mobile__mainContainer__mainList__panel__subContainer__subList__trigger__copy">
                          Menu Item 1's
                        </span>
                      </a> 
                    </li>
                    <li>
                      <button class="n-navigation__mobile__mainContainer__mainList__panel__subContainer__subList__trigger">
                        <span class="n-navigation__mobile__mainContainer__mainList__panel__subContainer__subList__trigger__copy">
                          Menu Item 1's
                        </span>
                        <span class="n-navigation__mobile__mainContainer__mainList__panel__subContainer__subList__trigger__icon"> 
                          > 
                        </span>
                      </button>
                      <div class="n-navigation__mobile__mainContainer__mainList__panel__subContainer__subList__panel">
                        <div class="n-navigation__mobile__mainContainer__mainList__panel__subContainer__subList__panel__container">
                          <button class="n-navigation__mobile__mainContainer__mainList__panel__subContainer__subList__panel__container__previous">Menu Item 1's</button>
                          <h3>Menu Item 1's</h3>
                          <ul class="n-navigation__mobile__mainContainer__mainList__panel__subContainer__subList__panel__container__list">
                            <li>
                              <a href="#" class="n-navigation__mobile__mainContainer__mainList__panel__subContainer__subList__panel__container__list__trigger">
                                <span>HiM.\\</span>
                              </a>
                            </li>
                            <li>
                               <a href="#" class="n-navigation__mobile__mainContainer__mainList__panel__subContainer__subList__panel__container__list__trigger">
                                <span>Herr\</span>
                              </a>
                            </li>
                          </ul>
                        </div>
                      </div>
                    </li>
                  </ul>
                </div>
              </div>
            </li>
            <li>
              <button class="n-navigation__mobile__mainContainer__mainList__trigger">
                <span class="n-navigation__mobile__mainContainer__mainList__trigger__copy">Menu Item 2</span>
                <span class="n-navigation__mobile__mainContainer__mainList__trigger__icon" aria-hidden="true"> > </s>
              </button>
              <div class="n-navigation__mobile__mainContainer__mainList__panel">
                <div class="n-navigation__mobile__mainContainer__mainList__panel__subContainer">
                  <button class="n-navigation__mobile__mainContainer__mainList__panel__subContainer__previous">All</button>
                  <h2>Menu Item 2</h2>
                  <ul class="n-navigation__mobile__mainContainer__mainList__panel__subContainer__subList">
                    <li>
                      <a href="#" class="n-navigation__mobile__mainContainer__mainList__panel__subContainer__subList__trigger">
                        <span class="n-navigation__mobile__mainContainer__mainList__panel__subContainer__subList__trigger__copy">
                          Menu Item 2's
                        </span>
                      </a>
                    </li>
                  </ul>
                </div>
              </div>
            </li>
            <li>
              <a href="#" class="n-navigation__mobile__mainContainer__mainList__trigger">
                <span class="n-navigation__mobile__mainContainer__mainList__trigger__copy">Menu Item 3</span>
              </a>
            </li>
          </ul>
        </div>
      </div>
    
      <div class="n-navigation__desktop"></div>
      <div class="n-navigation__iconMenu">
        search and cart
      </div>
      <div class="n-navigation__blur n-navigation__blur--hide"></div>
    </nav>