Hamburger Menu Icons (Three Line Menu Icon / Navicon) Different Ways

Avatar of Chris Coyier
Chris Coyier on (Updated on )

A universal symbol for “menu” has been on a lot of people’s minds lately. (“Navicon”, get it?!). Jordan Moore wrote up a big article on it for Smashing Magazine. Jeremy Keith wrote about it. Stuart Robson wrote about it. Tim Kadlec wrote about it. If you want to read more about the thinking behind this stuff and see examples, read those.

In this article, I’m going to focus on the “three-line” symbol (as opposed to down arrows or other possible navicons). I quite like the three-line symbol as a symbol to represent menus. If we have to pick one, I’m all for this one.

We’re going to look at the “how” to create this symbol in a bunch of different ways.

threelines

Use an Image

How have we put symbols onto websites for… ever? Images. There is nothing wrong with this. This image is so simple it begs for SVG. SVG means it’s 1) super small file size and 2) can scale to any size crisply. The HTML would probably be:

<a href="#menu">
  <img src="menu.svg" alt="">
  Menu
</a>

If you are going to use the symbol unaccompanied by text, make sure to include the alt text. You could use a PNG or whatever also, but SVG is perfect for this kind of simple drawing.

Use a Pseudo Element

There is nothing wrong with using an element, but if we use a pseudo-element and some trickery, we could make this symbol without the extra HTTP request that an image requires. (Yeah, it could be in your sprite, but you know what I mean).

Pseudo box-shadow

Nothing but semantic markup:

<a href="#menu" class="box-shadow-menu">
  Menu
</a>

In CSS, make some space on the left of the link with some padding-left. Set the positioning context with relative positioning. Then make a single black line absolutely positioned into that space on the top left. Then using box-shadow, make two more lines beneath it.

.box-shadow-menu {
  position: relative;
  padding-left: 1.25em;
}
.box-shadow-menu:before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.25em;
  width: 1em;
  height: 0.15em;
  background: black;
  box-shadow: 
    0 0.25em 0 0 black,
    0 0.5em 0 0 black;
}

Pseudo gradient

Same markup as the one above. The same idea of creating a space for the pseudo-element to go. Only this time, use gradients to create the three lines. Remember gradients don’t actually need to fade color from one to another if you use “hard stops” where the color changes to another instantly at the same color-stop.

.gradient-menu {
  padding-left: 1.25em;
  position: relative;
}
.gradient-menu:before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.21em;
  bottom: 0.21em;
  width: 1em;
  background: linear-gradient(
    to bottom, 
    black, black 20%, 
    white 20%, white 40%, 
    black 40%, black 60%, 
    white 60%, white 80%, 
    black 80%, black 100%
  );
}

Pseudo border

Credit to Mr. Robson on this one. He created it by applying a double and a single solid border to the pseudo-element. He also used pixel values in his demo. Tim Kadlec converted them to ems so they scale with text which is nice.

.border-menu {
  position: relative;
  padding-left: 1.25em;
}
.border-menu:before {
  content: "";
  position: absolute;
  top: 0.25em;
  left: 0;
  width: 1em;
  height: 0.125em;
  border-top: 0.375em double #000;
  border-bottom: 0.125em solid #000;
}

Use Fonts

There is a unicode symbol with three lines in it.

<a href="#menu">
  &#9776; Menu
</a>

You would think that would be perfect, but in reality, it ends up quite blurry. Looks OK on my retina display but pretty bad on non-retina. This kind of thing should be as crisp as can be anywhere.

You could always use an icon font as well. Entypo has this symbol in their free set. The lines are rounded, which looks good to me. Pictos has one with dot-line dot-line dot-line which is also good.

I haven’t had too much trouble with icon fonts being blurry like that Unicode icon is. I have no clue why that it, but c’est la vie.

Update: reader G S writes in:

Regarding the article https://css-tricks.com/three-line-menu-navicon/, an older Nokia phone with Opera 12 is able to display the unicode character for ‘IDENTICAL TO’ (U+2261), but not the TRIGRAM FOR HEAVEN’ (U+2630).

It would seem that a mathematical operator is more likely to be implemented in fonts than an iChing symbol.

Which is best?

I’d probably avoid the Unicode symbol as it doesn’t have the correct semantic meaning. I’d probably avoid making an HTTP request for an image just for this. The gradient thing is nice, but it’s a good size chunk of code to maintain.

I’d probably go for inline SVG.