'How to add overlay to sidenav menu?

I have a sidenav menu with some Js, I would like to add the overlay but I don't know how to do it, sorry but I'm a beginner. I tried several ways without success, even with a div that closes all content, but then I took it out because it broke the menu function. Can someone help me ? I appreciate any response, thanks.

 const toggle = document.getElementById('toggle');
    const sidenav = document.getElementById('sidenav');
    
    document.onclick = function(e){
        if(e.target.id !== 'sidenav' && e.target.id !== 'toggle' ) {
          toggle.classList.remove('active');
          sidenav.classList.remove('active');
        }
    }
    
    toggle.onclick = function(){
        toggle.classList.toggle('active');
        sidenav.classList.toggle('active');
    }
#toggle {
    display: flex;
    align-content: center;
    justify-content: flex-end;
    align-items: center;
    font-size: 18px;
    margin: 10px;
    padding: 10px;
    color: black;
    border: 1px solid black;
}

#toggle::before {
    font-family: fontAwesome;
    content:'Menu Closed';
    color: black;
    
}

#toggle.active::before {
    font-family: fontAwesome;
    content:'Menu Open';
    color: black;
}

/*Sidebar*/
.sidenav_box {
    margin-top: 10%;
    padding: 25px;
}

#sidenav {
    position: fixed;
    top: 0;
    left:-100%;
    width: 80%;
    height: 100vh;
    background: black;
    transition: 0.3s;
    z-index: 999;
}

#sidenav.active {
    left: 0px;
    width: 80%;
}
<div id="toggle"></div>

<div id="sidenav">
    
 <div class="sidenav_box"> 
  <div class="user_menu header">
        <span class="display name">Ciao [display_name]</span>
        <span class="display mail">[display_email]</span>
    </div>   
      
     <hr class="solid">  
     
    <div class="user_menu item">
        <a href="/account">
         <i class="icn_menu fa-regular fa-user"></i>
         <span class="link_text">Dashboard</span>
        </a>
    </div>
    
     <div class="user_menu item">
        <a href="ordini">
         <i class="icn_menu fa-regular fa-basket-shopping"></i>
         <span class="link_text">I miei ordini</span>
        </a>
    </div>
    
    <div class="user_menu item">
        <a href="libreria">
         <i class="icn_menu fa-regular fa-cloud-arrow-down"></i>
         <span class="link_text">Downloads</span>
        </a>
    </div>
    
    <div class="user_menu item">
        <a href="impostazioni">
         <i class="icn_menu fa-regular fa-gear"></i>
         <span class="link_text">Impostazioni</span>
        </a>
    </div>
    
    <div class="user_menu item">
        <a href="wp-login.php?action=logout">
         <i class="icn_menu fa-regular fa-arrow-right-from-bracket"></i>
         <span class="link_text">Logout</span>
        </a>
    </div>
   </div>
   
 </div>


Solution 1:[1]

When you say div with overlay, do you mean having the background of your nav menu be semi-transparent like so? If so you just need the opacity attribute but you might need to drop the z-index down if you want it to appear behind your other elements like the nav items.

const toggle = document.getElementById('toggle');
const sidenav = document.getElementById('sidenav');
const overlay = document.getElementById('contentOverlay');

document.onclick = function(e) {
  if (e.target.id !== 'sidenav' && e.target.id !== 'toggle') {
    toggle.classList.remove('active');
    sidenav.classList.remove('active');
    overlay.classList.remove('active');
  }
}

toggle.onclick = function() {
  toggle.classList.toggle('active');
  sidenav.classList.toggle('active');
  overlay.classList.toggle('active');
}
#toggle {
  display: flex;
  align-content: center;
  justify-content: flex-end;
  align-items: center;
  font-size: 18px;
  margin: 10px;
  padding: 10px;
  color: black;
  border: 1px solid black;
}

#toggle::before {
  font-family: fontAwesome;
  content: 'Menu Closed';
  color: black;
}

#toggle.active::before {
  font-family: fontAwesome;
  content: 'Menu Open';
  color: black;
}


/*Sidebar*/

.sidenav_box {
  margin-top: 10%;
  padding: 25px;
}

#sidenav {
  position: fixed;
  top: 0;
  left: -100%;
  width: 50%;
  height: 100vh;
  background: black;
  opacity: 1;
  transition: 0.3s;
  z-index: 999;
}

#sidenav.active {
  left: 0px;
  width: 50%;
}

#contentOverlay {
  position: fixed;
  top: 0;
  left: -100%;
  width: 100%;
  height: 100vh;
  opacity: 1;
  object-fit: cover;
  transition: 0.3s;
  z-index: 1;
}

#contentOverlay.active {
  left: 0px;
  width: 100%;
}
<div id="toggle"></div>

<div id="sidenav">
  <div class="sidenav_box">
    <div class="user_menu header">
      <span class="display name">Ciao [display_name]</span>
      <span class="display mail">[display_email]</span>
    </div>
  </div>

  <hr class="solid">

  <div class="user_menu item">
    <a href="/account">
      <i class="icn_menu fa-regular fa-user"></i>
      <span class="link_text">Dashboard</span>
    </a>
  </div>

  <div class="user_menu item">
    <a href="ordini">
      <i class="icn_menu fa-regular fa-basket-shopping"></i>
      <span class="link_text">I miei ordini</span>
    </a>
  </div>

  <div class="user_menu item">
    <a href="libreria">
      <i class="icn_menu fa-regular fa-cloud-arrow-down"></i>
      <span class="link_text">Downloads</span>
    </a>
  </div>

  <div class="user_menu item">
    <a href="impostazioni">
      <i class="icn_menu fa-regular fa-gear"></i>
      <span class="link_text">Impostazioni</span>
    </a>
  </div>

  <div class="user_menu item">
    <a href="wp-login.php?action=logout">
      <i class="icn_menu fa-regular fa-arrow-right-from-bracket"></i>
      <span class="link_text">Logout</span>
    </a>
  </div>
</div>
<img src="https://i.imgur.com/rsSBOSd.jpeg" id="contentOverlay" />

Solution 2:[2]

the way i add overlay is i wrap all the content within another div and use a ::after , then i color the after element, then i apply a z-index for the content inside to show up on top, something like this -

    header .nav-div {
    z-index: 1004;
    margin-left: 0;
    height: 100vh;
    width: 100vw;
    position: fixed;
    top: 0;
    left: 0;
    clip-path: polygon(0 0, 0 0, 0 100%, 0% 100%);
    transition: clip-path 0.3s linear;
  }
  header .nav-div::after {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-color: black;
    opacity: 0.75;
  }
  header .nav-div.active {
    clip-path: polygon(0 0, 100% 0, 100% 100%, 0% 100%);
  }
  header .nav-div .close {
    display: inline-block;
    height: 2rem;
    position: absolute;
    top: 2rem;
    right: 2rem;
    cursor: pointer;
  }
  header .nav-div .nav-div-mobile {
    z-index: 1005;
    background-color: white;
    height: 100%;
    width: 70%;
  }

here .nav-div::after is working as my overlay.

If, I put a opacity on .nav-div this will reduce opacity on all my content inside it. Hence, I put the opacity on the ::after which covers the entire .nav-div, and my main nav tag is inside my .nav-div-mobile(for extra styling purpose).

Putting the .nav-div-mobile on top of the .nav-div is important otherwise it will be behind the colored ::after element

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Shihab Munshi