DEV Community

Cover image for How to create an animated hamburger menu
Alfred Nwanokwai
Alfred Nwanokwai

Posted on

How to create an animated hamburger menu

In today's fast-paced digital world, capturing user attention is crucial. A well-designed website not only looks good but also provides a seamless user experience. One way to achieve this is by incorporating interactive elements, like an animated hamburger menu.

What is a hamburger menu?

A hamburger menu, also known as a three-line menu, is a popular navigation icon commonly used on websites, especially on mobile devices. It consists of three horizontal lines stacked on top of each other, resembling a hamburger patty. When clicked, it expands to reveal the website's navigation links.

Why animate your hamburger menu?

Static hamburger menus can sometimes appear bland and uninviting. Adding an animation can bring your menu to life, making it more visually appealing and engaging for users. This can lead to:

  • Increased user interaction: A dynamic menu can spark curiosity and encourage users to explore your website's navigation.

  • Enhanced user experience: A smooth and visually pleasing animation can elevate the overall user experience on your website.

  • Improved brand identity: A unique and creative animation can contribute to your website's brand personality and leave a lasting impression on visitors.

Creating an animated hamburger menu with CSS

create an index.html file

<!DOCTYPE html>

<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Animated Hamburger Menu</title>
  <link rel="stylesheet" href="./css/style.css" />
</head>

<body class="flex">
  <div class="frame flex">
    <div class="hamburger">
      <div class="hamburger__animated hamburger--before"></div>
      <div class="hamburger__animated"></div>
      <div class="hamburger__animated hamburger--after"></div>
    </div>
  </div>
  <script src="./js/script.js"></script>
</body>

</html>
Enter fullscreen mode Exit fullscreen mode

Hamburger Menu Styling: The .hamburger class styles the overall hamburger menu element, including its position, height, width, cursor, and hover effect.

.hamburger {
  position: relative;
  height: 40px;
  width: 80px;
  cursor: pointer;
}
Enter fullscreen mode Exit fullscreen mode

Animated Lines: The .hamburger__animated class styles the three lines of the hamburger menu. It defines their position, width, height, background color, transition properties, and border-radius. The .hamburger--before and .hamburger--after classes target the top and bottom lines of the menu, respectively.

.hamburger__animated {
  position: absolute;
  width: 80px;
  height: 8px;
  background: #fff;
  transition: all ease-in-out 0.2s;
  top: 2rem;
  border-radius: 10px;
  box-shadow: 1px 2px 3px rgba(0, 0, 0, 0.2);
}

.hamburger--before {
  top: 0rem;
}

.hamburger--after {
  top: 1rem;
}
Enter fullscreen mode Exit fullscreen mode

Hover Animation: The hover state of the .hamburger element triggers various animation effects on the lines using additional classes like .hamburger__animated--top, .hamburger__animated--before-rotate, etc. These classes modify properties like top, transform, visibility, and width to create the animation.

.hamburger:hover
.hamburger__animated:not(.hamburger--before, .hamburger--after) {
  width: 60px;
}

.hamburger:hover .hamburger--after {
  width: 70px;
}

.hamburger__animated--top {
  top: 0.5rem;
}

.hamburger__animated--before-rotate {
  transform: rotate(45deg);
  transition-delay: 0.2s;
}
.hamburger__animated--rotate {
  transform: rotate(-45deg);
  transition-delay: 0.2s;
}

.hamburger__animated--transparent {
  visibility: hidden;
}

.hamburger__animated--width {
  width: 80px !important;
}
Enter fullscreen mode Exit fullscreen mode

Added a little more CSS to make it look awesome

.flex {
  display: flex;
  justify-content: center;
  align-items: center;
}

body {
  background: #8a50f8;
  height: 100vh;
  margin: 0;
}

.frame {
  height: 400px;
  width: 400px;
  border-radius: 20px;
  background: linear-gradient(145deg, #9456ff, #7c48df);
  box-shadow: 13px 13px 22px #7946da, -13px -13px 22px #9b5aff;
}
Enter fullscreen mode Exit fullscreen mode

Here is the full CSS code.

/* General style */
.flex {
  display: flex;
  justify-content: center;
  align-items: center;
}

body {
  background: #8a50f8;
  height: 100vh;
  margin: 0;
}

.frame {
  height: 400px;
  width: 400px;
  border-radius: 20px;
  background: linear-gradient(145deg, #9456ff, #7c48df);
  box-shadow: 13px 13px 22px #7946da, -13px -13px 22px #9b5aff;
}

.hamburger {
  position: relative;
  height: 40px;
  width: 80px;
  cursor: pointer;
}

.hamburger__animated {
  position: absolute;
  width: 80px;
  height: 8px;
  background: #fff;
  transition: all ease-in-out 0.2s;
  top: 2rem;
  border-radius: 10px;
  box-shadow: 1px 2px 3px rgba(0, 0, 0, 0.2);
}

.hamburger--before {
  top: 0rem;
}

.hamburger--after {
  top: 1rem;
}
.hamburger:hover
.hamburger__animated:not(.hamburger--before, .hamburger--after) {
  width: 60px;
}

.hamburger:hover .hamburger--after {
  width: 70px;
}

.hamburger__animated--top {
  top: 0.5rem;
}

.hamburger__animated--before-rotate {
  transform: rotate(45deg);
  transition-delay: 0.2s;
}
.hamburger__animated--rotate {
  transform: rotate(-45deg);
  transition-delay: 0.2s;
}

.hamburger__animated--transparent {
  visibility: hidden;
}

.hamburger__animated--width {
  width: 80px !important;
}

Enter fullscreen mode Exit fullscreen mode

Here is the full JavaScript code.

const hamburger = document.querySelector(".hamburger");
const burger = document.querySelectorAll(".hamburger__animated");

/*
* Initializes a boolean variable named 
* showMenu to false,  indicating that 
* the menu is initially hidden.
**/
 let showMenu = false;

/**
 * a function named rotate that 
 * handles the animation of the 
 * hamburger menu icon
**/
const rotate = () => {
  for (i = 0; i < burger.length; i++)
    burger[0].classList.add("hamburger__animated--transparent");
  burger[1].classList.add("hamburger__animated--rotate");
  burger[2].classList.add("hamburger__animated--before-rotate");
};

/*
 * The function body uses an 
 * `if...else` statement to 
 * handle two scenarios: showing 
 * and hiding the menu.
**/
const toggleMenu = () => {
  if (!showMenu) {
    for (let i = 0; i < burger.length; i++) {
      burger[i].classList.add("hamburger__animated--width");
      burger[i].classList.add("hamburger__animated--top");
    }
    setTimeout(rotate, 0);
    showMenu = true;
  } else {
    for (i = 1; i < burger.length; i++)
      burger[1].classList.remove("hamburger__animated--rotate");
    burger[2].classList.remove("hamburger__animated--before-rotate");

    const rotate = () => {
      for (let i = 0; i < burger.length; i++) {
        burger[i].classList.remove(
          "hamburger__animated--top",
          "hamburger__animated--transparent",
          "hamburger__animated--width"
        );
      }
    };
    setTimeout(rotate, 200);

    showMenu = false;
  }
};
hamburger.addEventListener("click", toggleMenu);

Enter fullscreen mode Exit fullscreen mode

Top comments (0)