Svg transformation: Hamburger Icon to Close button

This is simple guide to creating hamburger icons that transform to close (x) button.

Here is the jsx for react/next.js

export default function MenuIcon() {
    return (
        <svg
            height="25px"
            viewBox="0 0 48 48"
            fill="none"
            xmlns="http://www.w3.org/2000/svg"
            id="hamburger-icon"
        >
            <path
                d="M7.94977 11.9498H39.9498"
                stroke="#000000"
                strokeWidth={4}
                strokeLinecap="round"
                strokeLinejoin="round"
            />
            <path
                d="M7.94977 23.9498H39.9498"
                stroke="#000000"
                strokeWidth={4}
                strokeLinecap="round"
                strokeLinejoin="round"
            />
            <path
                d="M7.94977 35.9498H39.9498"
                stroke="#000000"
                strokeWidth={4}
                strokeLinecap="round"
                strokeLinejoin="round"
            />
        </svg>
    )
}

Here is the css:

@media (max-width: 640px) {
	#hamburger-icon path{
		transition: linear 0.2s all;
	}

	.navbar:has(#menu-toggle:checked) {
		.nav-expanded {
			width: 100%;
			display: flex;
			position: absolute;
			z-index: 999;
			top: 100%;
			left: 0%;
		}
		#hamburger-icon path:nth-child(1) {
			transform-origin : 20% 35%;
			transform: rotate(45deg) scale(1.2);
		}
		#hamburger-icon path:nth-child(2) {
			
			transform: translateX(50%) scaleX(0);
			opacity: 0;
		}
		#hamburger-icon path:nth-child(3) {
			transform-origin: 25% 70%;
			transform: rotate(-45deg) scale(1.2);
		}
	}
}

My implementation of Navbar uses a hidden checkbox to handle toggle. That's where the .navbar:has(#menu-toggle:checked) { comes from.

The .nav-expanded class is the class for the section that is shown when navbar is toggled. Otherwise it is hidden.

The main animation:

The main animation is just a simple transition of transformations for the 3 paths (3 dashes) in the hamburger icon.

#hamburger-icon path:nth-child(1) {
			transform-origin : 20% 35%;
			transform: rotate(45deg) scale(1.2);
		}
		#hamburger-icon path:nth-child(2) {
			
			transform: translateX(50%) scaleX(0);
			opacity: 0;
		}
		#hamburger-icon path:nth-child(3) {
			transform-origin: 25% 70%;
			transform: rotate(-45deg) scale(1.2);
		}

You can use your own code to trigger the class changes.

The preview

I have modified the code to fit the use case of my blog. You should modify it to fit yours.

<svg
   height="25px"
   viewBox="0 0 48 48"
   fill="none"
   xmlns="http://www.w3.org/2000/svg"
   id="hamburger-icon">
   <path
      d="M7.94977 11.9498H39.9498"
      stroke="#000000"
      strokeWidth="4px"
      strokeLinecap="round"
      strokeLinejoin="round"/>
   <path d="M7.94977 23.9498H39.9498" stroke="#000000" strokeWidth="4px" strokeLinecap="round"
      strokeLinejoin="round"/>
   <path
      d="M7.94977 35.9498H39.9498"
      stroke="#000000"
      strokeWidth="4px"
      strokeLinecap="round"
      strokeLinejoin="round"/>
</svg>
<style>
#hamburger-icon path{
    transition: linear 0.2s all;
}
#hamburger-icon:hover path:nth-child(1) {
transform-origin : 20% 35%;
transform: rotate(45deg) scale(1.2);
}
#hamburger-icon:hover path:nth-child(2) {
transform: translateX(50%) scaleX(0);
opacity: 0;
}
#hamburger-icon:hover path:nth-child(3) {
transform-origin: 25% 70%;
transform: rotate(-45deg) scale(1.2);
}
</style>

Happy Coding 🫡