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>
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>