javascripthtmlcsshamburger-menu

Hamburguer Menu slide-in animation going out of screen


I'm trying to do a hamburguer menu slide-in/out animation using HTML,CSS and JS but the starting point of the sidebar is out of screen (and out of the html body) which leaves a horizontal scroll. I have tried not use the 'position:absolute', but it doesn't seem to work.

Here is a picture of the problem:

Look at the horizontal scroll

The animation slide-in works fine, the problem is this horizontal scroll. Also: I don't know why the slide-out animation is not working.

function hamburguer_menu() {
  const botao_hamburguer = document.querySelector('#botao_hamburguer')
  const sidebar = document.querySelector('.sidebar')
  
  if (sidebar.style.opacity == 0) {
    sidebar.style.opacity = 1
    sidebar.style.translate = '0'
    sidebar.style.transition = 'translate ease-in 0.5s'
  } else {
    sidebar.style.opacity = 0
    sidebar.style.translate = '100%'
    sidebar.style.transition = 'translate ease-in 0.5s'
  }
}
html,
body {
  min-height: 100dvh;
  max-width: 100dvw;
  padding: 0;
  margin: 0;
}

#layout_bar {
  background-color: black;
  height: var(--heading_height);
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  align-items: center;
  box-shadow: #000000a1 1px 0px 9px 0px;
}

.botao_hamburguer {
  background-color: pink; /* transparent; */
  border: none;
  z-index: 2;
}

.sidebar {
  opacity: 0;
  transition: translate ease-in 0.5s;
  text-align: center;
  margin: 0;
  padding: 0;
  right: 0%;
  z-index: 1;
  position: absolute;
  translate: 100%;
  top: 0%;
  background-color: rgb(27, 27, 27);
  color: white;
  width: 300px;
  min-height: 100dvh;
}
<body>
  <!-- script src="/static/fit/js.js"></script -->
  
  <heading id="layout_bar">
    <h1 id="logo"><a href=""><span class="bigger">B</span>e<span class="bigger">B</span>etter</a></h1>
    <button type="button" onclick="hamburguer_menu()" id="botao_hamburguer" class="botao_hamburguer">
      <span class="material-symbols-outlined icon-branco">menu</span>
      <span class="material-symbols-outlined icon-branco" style="display: none;"></span>
    </button>
  </heading>

  <aside class="sidebar">
    <ul style="list-style-type: none;">
      <li>1</li>
      <li>2</li>
      <li>3</li>
      <li>4</li>
      <li>5</li>
      <li>6</li>
    </ul>
  </aside>

</body>


Solution

  • The problem is that translated elements leave behind their original boxes. You need to handle that extra space. I've put a box around your sidebar with hidden overflow.

    Notice also my revisions to your script. It's better to not manually apply styles in a script, but instead change CSS classes.

    I also removed some unneeded CSS properties from the sidebar, and zero values don't need units. Sidebar needed overflow hidden as well to properly contain the list.

    function hamburguer_menu() {
      document.querySelector('.sidebar').classList.toggle('in');
    }
    html,
    body {
      min-height: 100dvh;
      max-width: 100dvw;
      padding: 0;
      margin: 0;
    }
    
    #layout_bar {
      background-color: black;
      height: var(--heading_height);
      display: flex;
      flex-direction: row;
      justify-content: space-between;
      align-items: center;
      box-shadow: #000000a1 1px 0px 9px 0px;
    }
    
    .botao_hamburguer {
      background-color: pink;
      border: none;
      z-index: 2;
    }
    
    .sidebar-box {
      overflow: hidden;
      position: absolute;
      right: 0;
      top: 0;
    }
    
    .sidebar {
      overflow: hidden;
      opacity: 0;
      transition: all ease 0.5s;
      text-align: center;
      z-index: 1;
      margin-right: -100%;
      background-color: rgb(27, 27, 27);
      color: white;
      translate: 300px;
      width: 300px;
      min-height: 100dvh;
    }
    
    .sidebar.in {
      opacity: 1;
      margin-right: 0;
      translate: 0;
    }
    <body>
      <!-- script src="/static/fit/js.js"></script -->
    
      <heading id="layout_bar">
        <h1 id="logo"><a href=""><span class="bigger">B</span>e<span class="bigger">B</span>etter</a></h1>
    
        <button type="button" onclick="hamburguer_menu()" id="botao_hamburguer" class="botao_hamburguer">
          <span class="material-symbols-outlined icon-branco">menu</span>
          <span class="material-symbols-outlined icon-branco" style="display: none;"></span>
        </button>
      </heading>
    
      <div class="sidebar-box">
        <aside class="sidebar">
          <ul style="list-style-type: none;">
            <li>1</li>
            <li>2</li>
            <li>3</li>
            <li>4</li>
            <li>5</li>
            <li>6</li>
          </ul>
        </aside>
      </div>
    </body>