Video icon 64
Want to be a web designer? Skill up fast with video courses from Tuts+. Start your free trial.
Advertisement

7 Non-raster Approaches for Making the “Hamburger” Menu Icon

by

Whether you're a fan of the cheesy name or not, it seems the infamous “hamburger” menu icon is here to stay - at least for a while, anyway. 

As seen on TC
The Hamburger, as seen on TechCrunch

In this tutorial we'll look at a number of approaches to creating and styling such an icon without using raster images. I've got seven options to show you, so we better get cracking...

Why Non-raster?

Using an image is quick and simple so why bother looking for alternative approaches? Here are a few reasons which we'll use to measure the success of each of the potential solutions against:

  • Loading fewer assets reduces HTTP requests
  • Non-raster icons scale up (and down) infinitely for high density displays
  • We can add extra styling and interactivity with CSS
  • It's a nice challenge!

#1. Use SVG

We'll look at some examples of creating the menu icon with CSS in a moment, but my list would be incomplete without mentioning SVG images as a viable option.

If writing code isn't your strength, but you still want the benefit and scalability of image elements for high density displays, vector graphics in SVG format are a great option.

SVG can be used in a number of ways:

SVG <img>

SVG can be added to the src of an img tag just as you would with any other image format.

<img src="path/to/menu-icon.svg" alt="menu icon" width="70" height="50">

SVG background-image

The same SVG image could also be used as a background image in CSS

.menu-icon {
    width:70px;
    height:50px;
    background-image:url('path/to/menu-icon.svg');
}

Inline SVG

SVG can also be written inline using XML. If you export SVG from an application like Adobe Illustrator and open it in a code editor, you'll see what the underlying code looks like.

Screenshot of SVG code

Tip: copying objects from Illustrator, then pasting directly into a text editor will give you the SVG code too.

Although it might feel odd to copy and paste this XML into your page template, when taking this approach you can actually manipulate the styling of the individual elements of the SVG in CSS.

svg line {
    stroke: white;
}

Pretty nifty, eh?

For an even more impressive approach, it's possible to animate SVG. A great example of animating a menu icon can be seen in this fantastic tutorial from Kyle Henwood on Making a SVG HTML Burger Button.

Using SVG can reduce requests and allow manipulation through CSS if inlined as shown above. When using SVG as an img tag or CSS background-image the only criteria on my list that's satisfied is the infinite scalability. 

We can do better.

#2. Use an Icon Font

The second approach, is to use an Icon Font.

An icon font is just like any other custom typeface that you'd add via @font-face but instead of containing letters of the alphabet, it contains a series of symbols. These are often added to the page via the content property of a :before or :after pseudo element to keep the markup clean and tidy and free of presentational elements.

One of my favourite services for icon fonts is Icomoon which has a library of free icon fonts that you can pick and choose to create your own.

Screenshot from Icomoonio

To create a completely custom font of your own icon designs, there is a feature to upload your own SVG images via the “Import Icons” button. The app generates the font and all the code necessary for using your hand-made font, either by downloading the font files and CSS or using a link tag to hook up a hosted version of it in the head of your page. I've used this service a number of times across client projects and it's a real joy to use!

Icon fonts are scaleable (though being fonts they're subject to anti-aliasing) and can be manipulated as text in CSS but loading them onto the page does require additional requests for the font files and stylesheet. For more complex icons like some of those pictured above, this is a great approach but as the menu icon is so simple, we could probably make it using features in CSS.

#3. Bootstrap Method

CSS frameworks like ZURB Foundation or Twitter Bootstrap are very popular so perhaps we could look to these guys for a nice lean approach to creating our icon?

Bootstrap's JavaScript will automatically collapse dropdown menus for browsers less than 768px wide and replace them with a nav-bar toggle button. 

When using the web inspector to see how their icon was made, we see the following:

button element with four span elements inside; three of these are used to create the horizontal lines of the menu icon and the first one is for screen readers only as the "Toggle navigation" text is positioned off-screen.

The CSS added to each icon-bar sets a background colour for each bar along with the dimensions and very subtle rounded corners.

.navbar-default .navbar-toggle .icon-bar {
    background-color: #888;
}
.navbar-toggle .icon-bar {
    display: block;
    width: 22px;
    height: 2px;
    border-radius: 1px;
}

If slightly rounded corners on each horizontal line is important to you, then this approach is one of the few CSS options that will allow that effect to be achieved. 

Another benefit to splitting each line into its own element would be if you wanted to animate each one between the opened and closed states on toggle. A great example of this can be seen on the new Star Wars redesign.

I was a bit surprised to find that such a popular framework uses five separate elements to create this relatively simple UI element but I'm sure they had a good reason for doing so. I've seen a similar approach used elsewhere too (without Bootstrap) so it's certainly more common that I would have expected. Take a look at the source on Media Temple's site and you'll see they take the hamburger approach very literally!

<a href="#siteNav" class="hamburger js-menuLink" id="LuckyAnchor_518835807_2">
    <span class="hamburger-bun hamburger-bun--top"></span>
    <span class="hamburger-patty"></span>
    <span class="hamburger-bun hamburger-bun--btm"></span>
</a>

If you prefer to keep your markup as clean as possible, there are a few other methods we can look at; and they just use a single element...

#4. CSS Borders

The typical menu icon is very simple in design; just three horizontal lines. 

The first and last lines can be created with border-top and border-bottom of an anchor tag set to display:inline-block. The middle line can be added with a border on a pseudo :after element.

With the following HTML, we can build up some generic styles for each different approach with the menu-icon class and then add specific styles for this one using borders with the border-icon class.
<a href="#" class="menu-icon border-icon">menu icon</a>
body {
    background:#196e76; /* Tuts+ Green */
}
.menu-icon {
    position:relative;
    display:inline-block;
    width:70px;
    text-indent:-999px;
}

.border-icon {
    height:30px;
    border-top:10px solid #fff;
    border-bottom:10px solid #fff;
}

.border-icon:before {
    content:"";
    position:absolute; 
    top:10px;
    left:0;
    width:100%;
    border-top:10px solid #fff;
}

This approach has the deepest browser support; pseudo elements are supported in IE8 and above and borders and positioning are supported everywhere!

This method ticks all of our boxes for creating non-raster icons but there are a couple of other CSS approaches we could look at before picking a winner.

#5. CSS Box Shadow

If you're fortunate enough to not need IE8 support, there are a couple of alternatives available that use some slightly more recent features in CSS. I suppose if you only need to show the menu icon on mobile devices, you will be able to use any of these approaches without worrying about legacy browser support...

One approach is to use multiple box-shadow declarations with no blur to create a series of solid lines.

To ensure that the icon has the correct clickable area, the series of shadows has to be added via a pseudo element and then positioned so they appear as a layer beneath the a element.

.shadow-icon {
    height:40px;
}

.shadow-icon:after {
    content:"";
    position:absolute;
    top:-50px;
    left:0;
    width:100%;
    height:100%;
    box-shadow: 0 10px 0 #fff,
                0 20px 0 #196e76,
                0 30px 0 #fff,
                0 40px 0 #196e76,
                0 50px 0 #fff;
}

The only downside of this approach is that the icon will need to be placed on something with a solid background (ie. #196e76 for Tuts+ green) to get the striped shadows effect to work. I used #196e76 for Tuts+ green in this case but you would need to swap that out to match your background colour.

Again, this approach satisfies the list of requirements but the extra step of positioning the pseudo element to bring the visual part of the icon under the clickable part of it feels a bit of a hack to me. It looks great, but isn't the most elegant solution.

#6. CSS Gradients

The final CSS approach is the leanest. Using a single element, with no pseudo elements, we can create a series of horizontal lines for the icon using a single linear gradient with a series of colour stops.

I've used the unprefixed spec for gradients here to keep the example looking clean. To generate gradients and get the vendor prefixed variants, check out Colorzilla's CSS Gradient Generator.

.gradient-icon {
    height:50px;
    background:linear-gradient(to bottom, #fff 0%, #fff 20%, transparent 20%, transparent 40%, #fff 40%, #fff 60%, transparent 60%, transparent 80%, #fff 80%, #fff 100%);
}

This is the simplest and most flexible approach so far. The others are a bit fragile because if you want to tweak the sizing or positioning of them, you end up needing to tweak quite a few values. 

The issue of needing a solid background colour behind the icon is also removed here by using transparent colour stops in between the white lines.

As this gradient approach is made using percentage colour stops, making the icon wider or taller is as simple as changing the width and height properties of the element.

Out of the three CSS approaches, this is my favourite. If I was going to use CSS to create my icon, this is the one I'd use - and in fact, I've done so on my personal site. But before we wrap things up, there's just one more I want to show you...

#7. Use the Keyboard?

I've played around with all these approaches before but some are more suitable than others; browser support and flexibility are often a factor so if you'd like to use any of the above do take those factors into account.

However, I recently came across a much simpler, much easier approach while I was teaching a responsive web development class.

There is actually a character in the UTF-8 character set that is almost identical to the classic “hamburger” icon. I found it while looking for something completely different on Copy Paste Character in their graphic shapes section.

This special character:  ☰ is called the Trigram for Heaven. It's character U+2630 in unicode and is uncannily similar to the ubiquitous menu icon. It's one of eight Trigams which are a group of symbols that hold deep meaning in Chinese philosophy. For more info, you can read more about the eight Trigrams here.

To use it in your project, go to Copy Paste Character and click on the symbol which will copy it to your clipboard. Just paste into your text editor of choice where you'd like the "icon" to appear. You can also copy it directly from the body text in this article if you prefer.

You will want to make sure your document is using the UTF-8 character set as specified by a meta tag in the head of the page:

<meta charset="utf-8">

As this is just textual content, it can be styled in CSS to make it larger, give it spacing, change its colour and all manner of other things!

Recap

So, we looked at a number of ways to create and add a hamburger menu icon to a project. We looked at SVG and icon fonts and tackled three CSS-only approaches but eventually found the simplest solution of them all; using a unicode character. 

Using the "Trigram of Heaven" ticks all the requirements of not using raster images: it needs zero HTTP requests, its infinitely scalable for high density screens, it can be manipulated with CSS and is so simple, it frees us up to go in search of other exciting challenges to tackle! I guess it always pays to find a simple solution before diving in to getting crafty with your CSS...

If you have any additional approaches for creating the “hamburger” icon, I'd love to hear about them in the comments!

Advertisement