Animate hamburger icon to cross and vice versa using CSS

May 14, 2023 by Andreas Wik

 

Let’s have a look at how to create a neat animation that turns a hamburger icon into a cross and vice versa using CSS. This is what we will end up creating:

See the Pen Hamburger icon to cross and vice versa with CSS by Andreas Wik (@andreaswik) on CodePen.

 

 

Starting with the markup, let’s create a container for the burger icon and three div elements inside of it which will be the three lines.

<div class="hamburger">
    <div class="line line-1"></div>
    <div class="line line-2"></div>
    <div class="line line-3"></div>
</div>

 

Time for some CSS. First some basic setup, followed by the hamburger div container.

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

:root {
  font-size: 62.5%;
}

.hamburger {
  width: 5rem;
  height: 5rem;
  position: fixed;
  top: 2rem;
  right: 3rem;
  cursor: pointer;
  padding: 1rem;
  display: flex;
  flex-direction: column;
  justify-content: space-around;
}

So for the hamburger container div, we set a width and height of 5rem (50px), set the position to fixed to have it sit in the top right corner of the window. We also add a bit ofย  padding.

In order to have the three lines position nicely inside of the container we use flexbox with flex-direction set to column and justify-content set to space-around.

 

The three line elements will have a few styles in common, the .line class:

.line {
  width: 100%;
  height: 0.3rem;
  background-color: #333333;
  border-radius: 0.2rem;
  transition: all 0.5s ease-in-out;
}

Each line will take up the full width of the container and have a height of 0.3rem, I think that will look alright. We’ll give it a background-color and add a tiny bit of border-radius just to have the corners of the line a little rounded.

We’ll also add a transition effect to it, which will control the duration of our animation for each line. You don’t really have to add the ease-in-out effect, but I like the style of it so I’ll throw that in there.

 

Now, when the user clicks the hamburger container, we’ll toggle a class with name .clicked using a tiny bit of JavaScript, like so:

const hamburger = document.querySelector('.hamburger');

hamburger.addEventListener('click', () => {
  hamburger.classList.toggle('clicked');
});

 

With that done, we need to finalize the styles for each .line, starting with .line-1 (the top one). This one will rotate and become one of the lines for the cross, the one going diagonally from the top right to the bottom left. We do this using rotateZ and translate. Keep in mind that if you change the size or position etc of the lines or hamburger container (the code in the previous steps), you’ll also need to tweak these values to get it the way you want.

.clicked .line-1 {
  transform: rotateZ(-405deg) translate(-0.8rem, 0.6rem);
}

 

As for .line-2 (the middle one), we’ll just let that one fade out and “disappear”, simply setting the opacity to 0.

.clicked .line-2 { 
  opacity: 0;
}

 

.line-3 (the bottom one) will rotate and move to become the second line of the cross, the one going diagonally from the top left to the bottom right:

.clicked .line-3 {
  transform: rotateZ(405deg) translate(-0.8rem, -0.6rem);
}

 

That’s it!

Check out the CodePen below for a live working example and complete code:

See the Pen Hamburger icon to cross and vice versa with CSS by Andreas Wik (@andreaswik) on CodePen.

 

 

Share this article

Recommended articles