How to create a hamburger menu icon with CSS and JavaScript
Tags: css, webdev, design, javascript
Published: 2020-04-18 16:47:52

![Programmer and dog](https://images.unsplash.com/photo-1534120247760-c44c3e4a62f1?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2574&q=80)Photo by [Devin Edwards](https://unsplash.com/@devindtx?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) on [Unsplash](https://unsplash.com/s/photos/designer?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText)

Recently, I've been investing a lot of time in improving my frontend skills, especially in CSS and animation. As they say, if you want to be good at something, you have to put in a lot of practice. While working on my portfolio, I needed a hamburger menu icon, and because I didn't want to use any of the existing ones out there, I decided to create my own. 

## Prerequisites
All you need to follow along is basic HTML, CSS, and Javascript knowledge.

## Writing the HTML
The HTML is pretty straightforward; we have the container for the icon, the menu-icon and three lines nested within it.
```html
<div class="container">
  <div class="menu-icon">
    <span class="line-1"></span>
    <span class="line-2"></span>
    <span class="line-3"></span>
  </div>
</div>
```

## Basic styles for the page
This is just to centre the icon and make everything look nice.

```css
body {
  background: #09182F;
}

.container {
  width: 100%;
  height: 80vh;
  display: flex;
  align-items: center;
  justify-content: center;
}
```

## Styling the menu-icon
Using `grid`, we can easily position the menu-icon and the nested lines within. `place-items: center` is the swiss army knife that performs two functions; `align-items: center` and `justify-items: center`.
```scss
.menu-icon {
  display: grid;
  place-items: center;
  height: 55px;
  width: 50px;
  cursor: pointer;
}
```

### Styling the 3 lines
Add the following to style the nested lines. We're giving the first and second lines different widths to make the icon look less conventional.
```scss
.menu-icon {
...

  & > span {
    width: 50px;
    height: 3px;
    background: red;
    display: block;
    transition: all 0.3s ease-in-out;
  }
}

.line-1 {
  width: 42px;
  justify-self: end;
}
  
.line-2 {
  width: 35px;
  justify-self: end;
}
```


### Hover effect
On hover effect, we change the widths of the first and second lines. The transition makes the switch between the widths smooth and seamless.

```scss
.menu-icon {
...

  &:hover span:nth-child(1) {
    width: 35px;
  }
  
  &:hover span:nth-child(2) {    
    width: 40px;
  }
}
```

### Animating the icon onClick
Here comes the fun part. We want to make the first and third lines rotate to form an X when clicked and make the second line disappear. 

```scss
.menu-icon {
...

  &.active span:nth-child(1) {
    transform-origin: center center;
    transform: rotate(-45deg) translate(-12px, 12px);
    width: 55px;
  }
  
  &.active span:nth-child(2) {
    transform: translateX(10px);
    opacity: 0;
  }
  
  &.active span:nth-child(3) {
    transform-origin: center center;
    transform: rotate(45deg) translate(-15px, -14px);
    width: 55px;
  }
}
```
When the `menu-icon` is clicked, the `active` class is added, the 1st and 2nd `lines` are targeted, and we use the `rotate` & `translate` properties to form an X. Also, we hide the 2nd line by moving it using `translateX` and setting the opacity to 0. 

## Adding JavaScript
The only thing left is to add a little Js to toggle the `active` class.

```javascript
const menuIcon = document.querySelector('.menu-icon');

function toggleMenuIcon() {
  menuIcon.classList.toggle('active')
}

menuIcon.addEventListener('click', toggleMenuIcon);
```

And there you go. Our own custom-made hamburger menu icon. The final result is below.

{% codepen https://codepen.io/emmaadesile/pen/XWmdOWJ %}

Kindly like and leave a comment if you learnt something new.