Search code examples
htmlcssanimationcss-animations

Hamburger lines not centered when clicking on button


What I am trying to do is when the .btn-menu is clicked, I want the two-lined hamburger to change to an X. However, the lines don't get centered when this happens. What am I doing wrong?

I have the following HTML, CSS and JavaScript code:

const menuBtn = document.querySelector(".btn-menu");

    // Create menu animation
    menuBtn.addEventListener("click", function () {
    menuBtn.classList.toggle("transform"); 
    });
 .btn-menu {
    display: flex;
    justify-content: center;
    align-items: center;
    flex-direction: column;
    gap: 0.8rem;
    transition: all 0.6s;
  }

 .toggle-line {
    width: 5rem;
    height: 1rem;
    background-color: black;
    border-radius: 3px;
  }

  .is-top,
  .is-bottom {
     transition: all 0.5s;
  }

 .transform .is-top {
    transform: translateY(8px) rotate(45deg);
  }

 .transform .is-bottom {
    transform: translateY(-8px) rotate(-45deg);
 }
<div class="btn-menu" role="button">
    <div class="toggle-line is-top"></div>
    <div class="toggle-line is-bottom"></div>
</div>


Solution

  • I believe the piece of the puzzle you are missing is the transform-origin CSS property. This tells the browser where the center of the transform should be located. I've updated your code below to get the effect you desire.

    (Note: I removed the translateY transforms)

    const menuBtn = document.querySelector(".btn-menu");
    
        // Create menu animation
        menuBtn.addEventListener("click", function () {
        menuBtn.classList.toggle("transform"); 
        });
    .btn-menu {
            display: flex;
            justify-content: center;
            align-items: center;
            flex-direction: column;
            gap: 0.8rem;
            transition: all 0.6s;
          }
         
         .toggle-line {
            width: 5rem;
            height: 1rem;
            background-color: black;
            border-radius: 3px;
            transform-origin: 25% 50%;
          }
         
          .is-top,
          .is-bottom {
             transition: all 0.5s;
          }
         
         .transform .is-top {       
            transform: rotate(45deg);
          }
         
         .transform .is-bottom {        
            transform: rotate(-45deg);
         }
    <div class="btn-menu" role="button">
        <div class="toggle-line is-top"></div>
        <div class="toggle-line is-bottom"></div>
    </div>