I am trying to create a pure CSS-based hamburger menu toggle. This is the HTML, and CSS, that I'm using:
body{
margin: 0;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
gap: 3rem;
}
.menu-toggle-label span,
.menu-toggle-label span::before,
.menu-toggle-label span::after{
width: 50px;
height: 6px;
position: relative;
background-color: black;
display: block;
transition: all 400ms ease-in-out;
}
.menu-toggle-label span::before,
.menu-toggle-label span::after {
content: '';
position: absolute;
}
.menu-toggle-label span::before {
transform: translateY(-16px);
}
.menu-toggle-label span::after {
transform: translateY(16px);
}
.menu-toggle:checked~.menu-toggle-label>span {
transform: translateX(-50px);
opacity: 0;
}
.menu-toggle:checked~.menu-toggle-label>span::before {
transform: rotate(45deg) translate(35px, -35px);
}
.menu-toggle:checked~.menu-toggle-label>span::after {
transform: rotate(-45deg) translate(35px, 35px);
}
<input type="checkbox" id="menu-toggle" class="menu-toggle">
<nav></nav>
<label class="menu-toggle-label" for="menu-toggle">
<span></span>
</label>
When checkbox gets checked, I want to hide the main span element and transform its pseudo-element into a cross.
However, the style below selects its pseudo-elements instead of selecting only the main span element. So all of them get hidden.
.menu-toggle:checked ~ .menu-toggle-label > span {
transform: translateX(-50px);
opacity: 0;
}
change the background-color of the main span to match the background of its container when checked.
.menu-toggle:checked ~ .menu-toggle-label > span {
background-color: transparent; /* or whatever the container's background color is */
}
.menu-toggle:checked ~ .menu-toggle-label > span::before {
top: 0;
transform: rotate(45deg);
}
.menu-toggle:checked ~ .menu-toggle-label > span::after {
bottom: 0;
transform: rotate(-45deg);
}
Hopefully this should do the trick for you.