How to build a responsive responsive menu with CSS flexbox and JavaScript

Teri Eyenike
4 min readApr 29, 2020

In this article, we would take a deep dive into creating a responsive navigation bar menu using vanilla JavaScript with some basic styling and flexbox. So I would assume you have basic knowledge of HTML, CSS, and little bit of JavaScript. There are lots of tutorials out there on the web teaching you about responsive navigation menu, but I have found this process a lot simpler and faster integrating it to your already existing page.

This tutorial won’t be focused on media queries for all screen sizes.

Photo by Caspar Camille Rubin from Unsplash

Getting Started

Here’s is the HTML layout

For our HTML, we would be styling our hamburger menu which is the button using pseudo-classes.

You can see that our markup looks so ugly right now but we would be changing that with CSS.

Let’s add some basic styling to make look nice.

*,*:before,*:after {    padding: 0;    margin: 0;    box-sizing: border-box;}:root {    --darkbg: #222222;    --darklight: #ffeaff;    --red001: #ec0e0e;}html {   height: 100%;}body {    font-size: 16px;    font-family: Nunito, sans-serif;}.hamburger {    display: flex;    flex-direction: column;    justify-content: center;    align-items: center;    position: absolute;    cursor: pointer;    display: flex;    height: 50px;    width: 50px;    background: var(--darkbg);    border: 1px solid transparent;    top: 16px;    right: 16px;    z-index: 10;    transition: border 0.3s ease;}.hamburger:active {    outline: 5px solid var(--red001);}.main__nav {    display: flex;    flex-direction: column;    position: absolute;    justify-content: center;    align-items: center;    height: 100vh;    width: 100vw;    transition: transform 0.5s ease;}.main__nav a {    color: var(--darkbg);    font-size: 3rem;    padding: 0.2em 0;    margin: 0.6em;    text-decoration: none;    border-bottom: 1px solid transparent;    transition: border-bottom 1s ease;}.main__nav a:hover {    border-bottom: 1px solid var(--darklight);}

This certainly looks better.

With the help of CSS, we can strip off the default browser margin and padding using the universal selector(*) and setting box-sizing to border-box which helps the elements on the page to retain its size. I am using CSS variables. They are simply custom variables that contain specific values that can be reused throughout a document. Declaring a variable begins with a double dash( — ).

For the hamburger menu, it is making use of the absolute positioning to dictate where it should be on the page while declaring its width and height for the size of the menu. CSS transition provides a way to control animation speed when changing CSS properties.

For accessibility purpose, the .hamburger:active just enables us to give the user the ability to know exactly what is being selected.

.hamburger::after,.hamburger::before {    content: '';    height: 20px;    border-left: 1px solid var(--darklight);    transform: rotate(90deg);    margin: -3px;    transition: transform 0.3s ease;}.hamburger--active::after {    transform: rotate(-135deg);}.hamburger--active::before {    transform: rotate(-45deg);}.main__nav {display: flex;flex-direction: column;position: absolute;justify-content: center;align-items: center;height: 100vh;width: 100vw;background: var(--darkbg);transform: translateX(100%);transition: transform 0.5s ease;}.main__nav {    display: flex;    flex-direction: column;    position: absolute;    justify-content: center;    align-items: center;    height: 100vh;    width: 100vw;    background: var(--darkbg);

transform: translateX(100%);

    transition: transform 0.5s ease;}.main__nav--active {    transform: translateX(0);}

The pseudo-elements(::before, :: after) for the hamburger menu just helps to transform the border(the two line in between the box) and gives it the ability to rotate to the right-hand side of the page with a transition effect.

The transform property added to the .main__nav helps to push off the navigation links off the page and added back with a transform set to translateX(0) to help reposition the element horizontally on the 2D plane.

style.css

Now to the interesting part, JavaScript.

app.js

We would declare our variables and target it element using its id and adding an addEventListener to listen to both the hamburger menu and clicking on any part of the background closes the navbar. After this, invoke the handleNav() function. We are going to use the conditional flow if-else statement in how the menu responds to clicks.

The first statement simply states that if the nav contains the class name .main__nav — active and are there, they will either add or remove those class names negating it with the is not a (!) symbol or else remove the class name.

I hope that wasn’t too much to grasp at once. With this process, you can take on any existing and add a navigation menu.

--

--

Teri Eyenike

Teri is a software developer with years of experience in web development and technical writing based in Lagos, Nigeria. He treats content as products.