A Bunch of Hamburgers

If there is one new User Interface element that is sweeping the nation, it is the “hamburger” icon. Here is how I make my burgers from scratch.

Three HRs

A burger menu icon is, at is core, three horizontal lines. Amazingly, HTML ships with an HR tag for putting in a Horizontal Rule. So three of them stacked on top of each other is all we need! No images, no SVG, just some markup:

Three HRs




Ta-Da! Well, not exactly. They stretch across the whole container, which is not exactly what we want. So let us add a wrapper with a class name so we can reference it with some simple CSS to give us more of an icon feel:

Basic Burger





// MARKUP
<div class="burger-menu-wrapper">
    <hr>
    <hr>
    <hr>
</div>

// CSS
.burger-menu-wrapper {
    width: 23px;
    padding: 0;
    margin: 0;
}

And there we have it. The traditional “hamburger” icon. Technically, we could stop right here, but that would not be much of an article, so let us do some more!

Slightly Less Basic Burger

Let us pretend the boss is deeply offended by using plain old <hr> elements. “How gauche!” he says. “They need to match our beautiful magenta brand color. Make it so.” (Our boss apparently watches a lot of ST:TNG) So let us add a couple rules for that and a common class to all our HR elements so the rules can stick:

Pretty Burger





// MARKUP
<div class="burger-menu-wrapper">
    <hr class="burger-menu-line">
    <hr class="burger-menu-line">
    <hr class="burger-menu-line">
</div>

// CSS
.burger-menu-line {
    border: none;
    border-bottom: 2px magenta solid;
    padding: 0;
    margin: 0;
    margin-bottom: 6px;
}

You can achieve the color / style with a different set of CSS rules as well:

.burger-menu-line {
    border:none;
    background: magenta;
    height: 2px;
    /* padding and margin 
    rules are the same */
}

They wind up looking the same, so use whichever floats your boat. You can change the vertical spacing of your bars by tweaking the margins. Using that “math” stuff, you can make your icon perfectly square, or whatever shape / aspect ratio you want.

Perfect. We have a custom burger that we can make look however we want. Can we do more? Yep.

Your Burger Takes a Turn

Since 99.94618% of the time, you’ll be using the burger icon to open and close a menu, it would be cool to make the icon a close icon when the menu is open. “Why, you should have used images then!!” you say. Poppycock! We can use CSS still! Well, that and a teeny bit of JavaScript to add a class to the wrapper when we click.

We need to make an X out of things, since that is what a close icon looks like these days, which means we need to rotate the top and bottom lines, and make the center one vanish. Using the transform property will handle the former, and our old buddy opacity will take care of the latter. Before we make the whole package, let us take a moment to talk about transforms and more importatnly, transform origins.

Things spin from the center…

By default, an element that has a transform applied to it has that transform applied from the center of the element. For moves, this doesnt’ really matter all that much, as a move 20px up looks the same no matter where you start from. For rotations this does matter, as the transform origin is point that it will spin around. Imagine the tranform-origin property telling the browser to stick a pin the element at that spot. The element will spin around that pin when it is rotated.

A note about the CSS from here on.

To keep the code short, I’ve only included the non-prefixed versions of the transform and transition related properties. For greater broswer support, you’ll want to make sure you have the appropriate vendor prefixes for what you choose to support. Read about how to handle them with this nice CSS-Tricks article on the subject.

So, by default, we spin around center center, or the vertical and horizontal middle, like so: (that dotted line is a border I added for reference)

Default Origin Rotation



// MARKUP
<div id="default_origin" class="burger-menu-wrapper origin_example">
    <hr class="burger-menu-line burger-menu-top">
</div>

//CSS
.origin_example hr {
    transform:  rotate(45deg);
}            

So the center point of our HR stays in the center of the container, since by default that is where our pin got stuck.

…until we tell them not to.

We can move the pin by using the tranform-origin poperty. Let us move it over to the right side, centered vertically, and see what happens with that same transform:

Center Right Origin Rotation



// MARKUP
<div id="center_right_origin" class="burger-menu-wrapper origin_example">
    <hr class="burger-menu-line burger-menu-bottom">
</div>

//CSS
.origin_example hr {
    transform:  rotate(45deg);
}            
#center_right_origin hr {
    transform-origin: right center;
}

For fun, let us move it over to the left side and take a look at what we get:

Center Left Origin Rotation



// MARKUP

<div id="center_left_origin" class="burger-menu-wrapper origin_example">
    <hr class="burger-menu-line burger-menu-top">
</div>

//CSS

.origin_example hr {
    transform:  rotate(45deg);
}            
#center_left_origin hr {
    transform-origin: left center;
}
    

X Marks The Spot

Hey, that looks like what we want to do to the top line of our burger to make an X out of it! So using our new-found knowledge of origins, lets rotate the top and bottom lines from their left sides. We’ll have to rotate the bottom line the opposite way, so we use a negative value there. We’ll hide the center line with a zero opacity like we mentioned previously.

The X Burger





// MARKUP
<div id="x_nav_button" class="burger-menu-wrapper">
    <hr class="burger-menu-line burger-menu-top">
    <hr class="burger-menu-line burger-menu-center">
    <hr class="burger-menu-line burger-menu-bottom">
</div>

// CSS
#x_nav_button hr {
    transform-origin: left center;
}            
#x_nav_button .burger-menu-top {
    transform:  rotate(45deg);
}
#x_nav_button .burger-menu-bottom {
    transform:  rotate(-45deg);
}
#x_nav_button .burger-menu-center {
    opacity: 0;
}

Looks like a close button to me!

Awesome. Let us make it Awesomerer!

Now that we can bend (well actually rotate) our HRs to our will, lets see how we can transition between the two states. By making our transforms apply only when the wrapper has a specific class, we can jump back and forth between them by toggling that class on the wrapper. Go ahead and click / tap on that sucker. Go on!

Gourmet Burger





// MARKUP

<div id="fancy_nav_button" class="toggle_nav_button burger-menu-wrapper">
    <hr class="burger-menu-line burger-menu-top">
    <hr class="burger-menu-line burger-menu-center">
    <hr class="burger-menu-line burger-menu-bottom">
</div>

// CSS
.toggle_nav_button hr {
    transform-origin: left center;
}            
.toggle_nav_button.menu_shown .burger-menu-top {
    transform:  rotate(45deg);
}
.toggle_nav_button.menu_shown .burger-menu-bottom {
    transform:  rotate(-45deg);
}
.toggle_nav_button.menu_shown .burger-menu-center {
    opacity: 0;
}

// jQuery
$(function () {
    $('.toggle_nav_button').click(function () {
        $(this).toggleClass('menu_shown');
    });
});

So now we have an amazing cool toggleable buger / close button. It is the most amazing thing ever, quite possibly.

There Is No Possible Way This Could Be Any Better, Could It?

It Totally Could

If that was not cool enough, we can animate the transition by adding a couple addtional rules to our burger-menu-line block. Once again, click or tap on it to partake the goodness.

Super Deluxe Gourmet Burger





// MARKUP

<div id="super_fancy_nav_button" class="toggle_nav_button burger-menu-wrapper">
    <hr class="burger-menu-line burger-menu-top">
    <hr class="burger-menu-line burger-menu-center">
    <hr class="burger-menu-line burger-menu-bottom">
</div>

// CSS
/* All the rules from above apply here as well, plus... */
#super_fancy_nav_button .burger-menu-line {
  transition-property: all;
  transition-duration: 0.3s;
}

This causes any property change that can be animated via CSS to animate that change over three tenths of a second. You can do all sorts of neat things with transitions, so read up on them here.

Now Make a Menu Show Up.

All this talking about burgers has made me hungry, so I’m going to go eat. I’ll leave it up to you do make a menu pop up or slide out or fade in or whatever. Fill it with burger names so it is still appropriate.

back to top