Creating a CSS-only hamburger animation

By
Grant Vinson

The example:

See the Pen "100% CSS Hamburger Animation" by Grant Vinson (@vinsongrant) on CodePen.

What? An animated hamburger icon with no JavaScript?! That’s right, and it is pretty straightforward.

Determine interactions:

When creating and considering user interactions, we try to figure out the most performant/easy way to accomplish our goal. If you are comfortable with some JavaScript or jQuery, you probably know how to slide something up/down or add a CSS class to an element to add some animation. This is fine and dandy but what other options are available to us?

Capture user input with CSS:

We can use inputs to toggle between CSS properties. In the above example, we use a checkbox to toggle a hamburger animation.


When you click on a label that is tied to an input using the "for" attribute, the input element gains "focus". If you are using a radio/checkbox input, clicking their label will toggle its value. So, click on a checkbox label and you will check/uncheck that box. We can use this behavior to toggle our hamburger's styles.

Example explanation:

In my HTML, I have a checkbox followed by a label with the "hamburger" class applied. Inside of the label, I have 3 divs for the "top bun", "meat" and "bottom bun". The important part here is the order of the elements and the "for" attribute on the label. This will tie the label to the input.

<input id="toggle" type="checkbox"></input>
<label for="toggle" class="hamburger">
 <div class="top-bun"></div>
 <div class="meat"></div>
 <div class="bottom-bun"></div>
</label>

To determine if an input is "checked" or not, we can use one line of CSS:

input[type="checkbox"]:checked {
   /* Apply Styles Here */
}

Whenever the input is checked, we can apply our "opened menu" styles to our hamburger, like so:

#toggle:checked + .hamburger .top-bun {
 transform: rotate(-45deg);
 margin-top: 25px;
}
#toggle:checked + .hamburger .bottom-bun {
 opacity: 0;
 transform: rotate(45deg);
}
#toggle:checked + .hamburger .meat {
 transform: rotate(45deg);
 margin-top: -7px;
}

With a little ingenuity and research, we can accomplish amazing things. This isn't "amazing" by any means, but it is a unique way to achieve this particular goal. Guess what, we can use this technique in emails as well.