Whenever the top and bottom bars rotate, it isn’t centered on the middle. How can I fix this?
I want the 3 bars to form an X shape from the hamburger shape, but when the animation starts, the bottom and top bars get offset from the center when they rotate.
What I have currently:
function toggleState(target) {
target.classList.toggle("animate");
}
:root {
--btn-size: min(8vh, 8vw);
--bar-height: calc(var(--btn-size) / 5);
--margin-top: calc(var(--bar-height)*2);
--margin-bottom: calc(var(--bar-height)*-2);
--animation: 1s;
--anim-half: calc(var(--animation)/2);
--anim-func: ease-in-out;
--btn-color: #929292;
}
body {
height: max-content;
width: max-content;
margin: 5%;
}
#menu-btn {
height: var(--btn-size);
width: var(--btn-size);
display: flex;
align-items: center;
cursor: pointer;
}
#menu-icon,
#menu-icon::before,
#menu-icon::after {
height: var(--bar-height);
width: var(--btn-size);
background-color: var(--btn-color);
position: absolute;
transform-origin: center;
}
#menu-icon {
transition: rotate var(--animation) var(--anim-func) 0.00s;
}
#menu-icon::before {
transition: translate var(--anim-half) var(--anim-func) var(--anim-half), rotate var(--anim-half) var(--anim-func) 0.00s;
content: "";
transform: translateY(var(--margin-top));
}
#menu-icon::after {
transition: translate var(--anim-half) var(--anim-func) var(--anim-half), rotate var(--anim-half) var(--anim-func) 0.00s;
content: "";
transform: translateY(var(--margin-bottom));
}
.animate #menu-icon {
transition: rotate var(--animation) var(--anim-func) 0.00s;
rotate: 360deg;
}
.animate #menu-icon::before {
transition: translate var(--anim-half) var(--anim-func) 0.00s, rotate var(--anim-half) var(--anim-func) var(--anim-half);
translate: 0px var(--margin-bottom);
rotate: 45deg;
}
.animate #menu-icon::after {
transition: translate var(--anim-half) var(--anim-func) 0.00s, rotate var(--anim-half) var(--anim-func) var(--anim-half);
translate: 0px var(--margin-top);
rotate: -45deg;
}
<body>
<div id="menu-btn" onclick="toggleState(this)">
<div id="menu-icon" class=""></div>
</div>
</body>
<html>
I tried transform-origin: center on every line but it didn’t work. I expected it to rotate centered about the middle of the original.
2
Answers
I would consider a slightly different idea and simplify your code like below:
You’re trying to rotate the #menu-icon block inside of which there are &:before and &:after pseudo-elements. I’d suggest you use the following structure:
Then in the CSS, target the individual spans using span:nth-child(1), span:nth-child(2), and so on. This way, the #menu-icon itself isn’t part of the animation and there won’t be any unexpected rotations. To fix the offset during rotation, you can utilize the transform: translate property.