Hamburguer Menu slide-in animation going out of screen

52 Views Asked by At

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>

1

There are 1 best solutions below

2
isherwood On BEST ANSWER

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>