A beginner’s guide to animating hamburger icons using CSS3 transitions and transforms.

Made up of three parallel lines and stacked on top of one another, the hamburger icon is often used to direct users to features (usually a navigation) hidden off-screen. Although the hamburger has received quite a bit of criticism over the years , CSS3 allows us to jazz up this infamous symbol for times when we do use it. The Honest Beauty Blog has an awesome animation on their hamburger icon, which served as an inspiration to this blogpost.

This step-by-step guide will show you how to make a hamburger icon from scratch and how to animate it, using CSS transforms and transitions. For this example we will be animating the hamburger icon into a right arrow on hover. Understanding this example will help you figure out how to animate the icon in other ways. Check out the codepen for other examples (animating the icon into a left arrow and an x).

STEP 1: Make that hamburger.

Because we want to eventually animate the icon, we will have more control if we create our own hamburger instead using a font icon. There are many ways to create the hamburger icon, but for this example, I decided to make one using pseudo elements.


The nested span will become the middle line within our icon. Think of it as the patty to our delicious burger. Why nest our span in a div? It allows users to click/hover over a bigger area, rather than having to click on the spans themselves.

Now let’s start building the rest of our burger with CSS.


We will be positioning our main span (our patty) in relation to this div, which is why it has a position of relative.

Ideally you want your div to have the same height and width so it becomes a square. You should get something similar to this…

Let’s style that patty now - I mean our span:

Don’t worry about about the transition for now. We’ll need it later. You have to make the burger before you can eat it.

Here we set our main span to have a position of absolute and we will make it relative to its parent which is our div with a class of burger. (Remember to set position: relative; on the div.burger. Scroll back up if you missed it)

How’s this burger looking…

Cool. What this burger needs is some toppings. I’m feeling lettuce and tomato. Let’s make the before element the lettuce and the after element the tomato. (Bare with me, this burger analogy will help us when we get to using transitions and transforms, it’ll help us figure out which element is moving where).

Let’s create the ::before and ::after:


Phew. You just made your burger from scratch! Now the fun begins.

STEP 2: Add CSS Transition to your span.

If we want our burger to animate into a right arrow, we’ll have to play around with CSS Transforms. But let’s make our lives easier and set our span and pseudo spans to have a transition of 5 seconds first. Applying transitions allows us to control how long it will take to animate from state A (the spans without any transforms) to state B (the spans with transforms). Sure, setting our transition to 5 seconds is a bit much and our burger will look like its moving in sloooow-mo, but this will help us later when we’re deciding on what values to pair with our transforms property. We can always change the transition when we’re done.

Transitions are not supported by all browser, don’t forget those vendor prefixes!
Transitions are not supported by all browser, don’t forget those vendor prefixes!

Step 3: Decide how you want your burger icon to animate into the right arrow. Add CSS transforms.

A few things to consider before adding transforms.

Which span/pseudo element will end up where after those 5 seconds and how they will get there? Did you want some crazy spins? Something more subtle?

For this example, here’s what I had planned:

The ::after and ::before will rotate along with the main span. We have to think of where the lettuce and tomato will end up after the main span/patty transforms, and what final position we want the pseudo elements to be in, in relation to the patty.

Let’s break this down. Add transform: rotate(180deg); to the main span (our brown patty) when div.burger is in the state of hover:

We’ll have to add our vendor prefixes to all of our transforms, but let’s do it later.
It should animate like this on hover.

Now add transform: rotate(-45deg); to the ::before element (lettuce) and transform: rotate(45deg); to the ::after element (tomato).

You can adjust the rotation if you want more spins/movement in your animation.

STEP 4: Polish the burger.

Time to style the before/after elements on hover. Looks like we can shorten the width and play around with positioning to make this look more like a proper right arrow. Don’t forget to add vendor prefixes to those transforms.

Here’s how I styled mine:

I decided to add border-radius: 2px to the span and both of its pseudo elements.

Step 5: Pat yourself on the back (and maybe refactor your code).

Woohoo! Now you have a hamburger icon that’s just a bit cooler. Of course now you can change that transition to something less extreme. 1 second perhaps? And change the colours of the icon to match your website’s design. And don’t forget to add those vendor prefixes!

Here are some resources I found helpful while creating this:

CSS-TRICKS: transform

CSS-TRICKS: transitions

CSS-TRICKS: Three Line Menu Navicon

MDN: Pseudo-elements

Jesse Couch’s take on animating the hamburger

Here is my codepen, in case you wanted to review or see the other examples I created. The x example will require slightly different markup. It uses 3 different spans within the div, which is good for when you want even more control as none of the spans’ movement/animation will depend on the movement/animation of others.

Hoped this helped!