0

I've been trying to figure out how to make a menu button that functions similarly to that of YouTube, where once clicked the rest of the page is darker and inaccessible until the button is clicked once more and the menu retracts. If anyone could help with this, I would greatly appreciate it. (and if possible, still retaining most or all of my original code). :)

menuBtn = document.getElementsByClassName('menuButton')[0];
menuBtn.addEventListener('click', function() {
  menu = document.getElementsByClassName('linkList')[0];
  menu.style.webkitTransition = '0.6s';
  if (menu.style.right == '0px') {
    menu.style.right = '-150px';
  } else {
    menu.style.right = '0px';
  }
});
/* headerBar */

.headerBar {
  position: absolute;
  width: 100%;
  height: 80px;
  top: 0px;
  left: 0px;
  background-color: #b0b0b0;
}


/* headerStrip */

.headerStrip {
  position: absolute;
  width: 100%;
  height: 5px;
  top: 80px;
  left: 0px;
  background-color: #5e00bc
}


/* bodyBar */

.bodyBar {
  position: absolute;
  width: 100%;
  height: 100%;
  top: 85px;
  left: 0px;
  background-color: #000000
}


/* jobLinks styles */

.jobLinks {
  text-decoration: none;
  list-style: none;
}

.find {
  position: absolute;
  width: 80px;
  height: 40px;
  top: 30px;
  left: 300px;
  font-family: 'comfortaa';
  font-size: 18px;
  font-weight: 800;
  color: #000000;
  text-decoration: none;
  text-align: center;
  transition: ease-out 0.4s;
  background-color: #e0e0e0;
}

.find:hover {
  color: #5e00bc;
}


/* menu styles */

.menuButton {
  position: absolute;
  width: 30px;
  height: 30px;
  top: 25px;
  left: 1303px;
  border: none;
  outline: none;
  transition: ease-out 0.5s;
  background-image: url('/Images/Menu_Icon.png');
  background-color: #e0e0e0;
  cursor: pointer;
}

.links {
  font-family: 'comfortaa';
  font-size: 18px;
  font-weight: 500;
  color: #000000;
  text-decoration: none;
  transition: ease-out 0.4s;
}

.links:hover {
  color: #5e00bc;
}

.linkList {
  position: fixed;
  width: 150px;
  height: 100%;
  right: -150px;
  top: 85px;
  transition: ease-out 0.5s;
  background: #e0e0e0;
}

.linkList ul li {
  list-style: none;
  padding: 15px;
}

.menuButton:focus~.linkList {
  right: 0px;
}
<div class='headerBar'>
</div>

<div class='headerStrip'>
</div>

<div class='bodyBar'>
</div>

<div class='jobLinks'>
  <li><a class='find' href='#'>Find</a></li>
</div>

<div class='menu'>
  <button class='menuButton'></button>
  <div class='linkList'>
    <ul>
      <li><a class='links' href='#'>Link 1</a></li>
      <li><a class='links' href='#'>Link 2</a></li>
      <li><a class='links' href='#'>Link 3</a></li>
      <li><a class='links' href='#'>Link 4</a></li>
      <li><a class='links' href='#'>Link 5</a></li>
      <li><a class='links' href='#'>Link 6</a></li>
      <li><a class='links' href='#'>Link 7</a></li>
    </ul>
  </div>
</div>
Geeky Quentin
  • 2,469
  • 2
  • 7
  • 28
V4N464NDR
  • 7
  • 2

2 Answers2

2

Sorry OP, I know you asked for minimal change to your markup but what you were doing just seemed so backwards to me (also your snippet wasn't working for me??) -- take a look at the script in my snippet, I've set this up using click delegation on the body. This will detect every click anywhere on the page, but will only toggle the class if an element with id="toggle" is clicked.

As for the other parts, I had to add an overlay div which acts as the backdrop to the link list, this will cover the content. The overlay and the link list has z-index: 999 to make sure it will be above any absolute/relative/fixed position elements (so long as it has a z-index of less than 999). It doesn't cover the menu as this is where the button is to hide the overlay again, although clicking on the overlay will also hide it

I've also used display: grid a lot as this is much easier for the browser to calculate before painting than all the absolute positioned elements you had before

const main = document.getElementById('main');

document.addEventListener('click', function(e) {
  e.target.id === 'toggle' && main.classList.toggle('active');
  e.target.id === 'overlay' && main.classList.toggle('active');
},false );
* { box-sizing: border-box } body { margin: 0 }

main {
  display: grid;
  grid-template-rows: 85px 1fr;

  height: 100vh;
  
  overflow: hidden
}

header {
  grid-area: 1/1/2/2;
  
  display: grid;

  background-color: #b0b0b0;
  border-bottom: 5px solid #5e00bc
}

#find, #toggle {
  grid-area: 1/1/-1/-1;
  margin: auto;
  
  padding: 0.5em 1em;

  background-color: #e0e0e0;
  border: 0;
  border-radius: 0.375em;
  cursor: pointer;
  font-family: 'Comfortaa', cursive;
  font-size: 18px;
  font-weight: 800;
  line-height: 1;

  user-select: none; -moz-user-select: none; -webkit-user-select: none;

  transition: color 400ms 0ms ease-in-out
}
#find:hover, #toggle:hover { color: #5e00bc }
#toggle {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 448 512' height='18' width='18'%3E%3Cpath fill='currentColor' d='M0 96C0 78.33 14.33 64 32 64H416C433.7 64 448 78.33 448 96C448 113.7 433.7 128 416 128H32C14.33 128 0 113.7 0 96zM0 256C0 238.3 14.33 224 32 224H416C433.7 224 448 238.3 448 256C448 273.7 433.7 288 416 288H32C14.33 288 0 273.7 0 256zM416 448H32C14.33 448 0 433.7 0 416C0 398.3 14.33 384 32 384H416C433.7 384 448 398.3 448 416C448 433.7 433.7 448 416 448z'/%3E%3C/svg%3E");
  background-position: center;
  background-repeat: no-repeat;
  margin-right: 1em
}


section {
  grid-area: 2/1/3/2;
  
  background-color: black;
  color: white;
  font-family: 'comfortaa';
  overflow: scroll;
  padding: 1.5em
}

#overlay, #linkList {
  grid-area: 2/1/3/2;
  z-index: 999;

  transform: translateY( 100vh );
  
  transition: transform 600ms 0ms ease-in-out
}

#overlay {  
  background: #5e00bc;
  opacity: 0.825
}
#linkList {
  display: flex;
  flex-direction: column;
  margin: auto;
  max-height: 100%;
  overflow: scroll;
  padding: 0 1em
}
#linkList a {
  background-color: rgba(0, 0, 0, 0.5 );
  border-radius: 0.375em;
  color: white;
  font-family: 'comfortaa';
  font-size: 18px;
  font-weight: 700;
  margin-bottom: 0.25em;
  padding: 0.5em;
  text-decoration: none;
  
  transition: background-color 400ms 0ms ease-in-out, color 400ms 0ms ease-in-out, transform 400ms 0ms ease-in-out
}
#linkList a:hover {
  color: #5e00bc;
  background-color: white;
  transform: scale(1.075)
}

#linkList a:first-child { margin-top: 1em }
#linkList a:last-child { margin-bottom: 1em }

#main.active #overlay,
#main.active #linkList {
  transform: translateY( 0 );
}
<link href="https://fonts.googleapis.com/css2?family=Comfortaa:wght@400;500;600;700&display=swap" rel="stylesheet">

<main id="main">
  <header>
    <button id="find">Find</button>
    <button id="toggle">&nbsp;</button>
  </header>
  <section>
    <p>Nunc a porta a lacus a vitae a vulputate a a a class scelerisque sociosqu parturient habitant a quam platea nec a purus sem accumsan dui mauris dis. A pharetra mi porta parturient ultrices ac nisi ad aliquet taciti ullamcorper consequat ullamcorper conubia rhoncus magnis a condimentum risus in at suspendisse cum himenaeos non per ante.</p>
  </section>
  <div id="overlay"></div>
  <div id='linkList'>
    <a href='#'>This is Link 1</a>
    <a href='#'>This is Link 2</a>
    <a href='#'>This is Link 3</a>
    <a href='#'>This is Link 4</a>
    <a href='#'>This is Link 5</a>
    <a href='#'>This is Link 6</a>
    <a href='#'>This is Link 7</a>
  </div>
</main>
Simp4Code
  • 1,394
  • 1
  • 2
  • 11
0

I can only think of adding a that acts as an overlay that covers the entire page indexed at the back of the menu, at 100vh/vw with fixed position with display:none by default but onclick, you'll change the display property inline/inline-block.

John Dev
  • 11
  • 2
  • "I can only think of adding a `
    `" ** (I forgot to format if properly)
    – John Dev Jul 06 '22 at 01:03
  • Thank you guys so much for taking time out of your day to help me! I appreciate it – V4N464NDR Jul 06 '22 at 02:48
  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Francisco Maria Calisto Jul 06 '22 at 12:57