Responsive navigation menu with plain JavaScript
Linh Truong Cong Hong
Posted on September 30, 2020
Source code of this blog post could be found at:
https://github.com/linhtch90/devto-responsive-nav-plain-js.git
Showcase:
https://linhtch90.github.io/devto-responsive-nav-plain-js/
Introduction
Making a responsive navigation menu is a common task of frontend developers. The purpose of this blog post is to introduce necessary steps to build up a navigation menu which disappears at small screen (less than 600px) and get replaced by a hamburger button.
Main functions include:
When you press the hamburger button: A side menu show up and the hamburger button is replace by a close button.
When you press the close button or any menu item: The side bar collapses and the hamburger button show up again.
Step 1
Let's make a simple webpage with html for demonstration purpose as below and save it as ./index.html
Please make sure that you also create folders for css and javascript files with similar names and paths as mentioned in the html file which is ./css/style.css
and ./js/hamburger.js
, respectively.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<!-- Styling -->
<link rel="stylesheet" href="./css/style.css" />
<!-- Google font: Open sans -->
<link
href="https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;600;700;800&display=swap"
rel="stylesheet"
/>
<!-- Fontawesome -->
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.14.0/css/all.min.css"
/>
<title>
Responsive navigation menu example
</title>
</head>
<body>
<div id="ham-button" class="hamburger-button" onclick="hamburgerMenu()">
<i id="ham-icon" class="fas fa-bars"></i>
</div>
<div id="ham-menu" class="hamburger-menu">
<ul>
<li>
<a href="#navigation"><div onclick="hamburgerMenu()">Home</div></a>
</li>
<li>
<a href="#about"><div onclick="hamburgerMenu()">About</div></a>
</li>
<li>
<a href="#projects"><div onclick="hamburgerMenu()">Projects</div></a>
</li>
<li>
<a href="#blog"><div onclick="hamburgerMenu()">Blogs</div></a>
</li>
<li>
<a href="#footer"><div onclick="hamburgerMenu()">Contact</div></a>
</li>
</ul>
</div>
<!-- Navigation bar -->
<section id="navigation">
<div class="container-dark">
<nav class="navigation-bar">
<ul>
<li><a href="#navigation">Home</a></li>
<li><a href="#about">About</a></li>
<li><a href="#projects">Projects</a></li>
<li><a href="#blog">Blogs</a></li>
<li><a href="#footer">Contact</a></li>
</ul>
</nav>
</div>
</section>
<!-- Home -->
<section id="home">
<div class="container-dark">
<div class="container-home">Home</div>
</div>
</section>
<!-- About -->
<section id="about">
<div class="container-light">
<div class="container-about">About</div>
</div>
</section>
<!-- Projects -->
<section id="projects">
<div class="container-dark">
<div class="container-projects">Projects</div>
</div>
</section>
<!-- Skills -->
<section id="skills">
<div class="container-light">
<div class="container-skills">Skills</div>
</div>
</section>
<!-- Timeline -->
<section id="timeline">
<div class="container-dark">
<div class="container-timeline">Timeline</div>
</div>
</section>
<!-- Blog -->
<section id="blog">
<div class="container-light">
<div class="container-blog">Blog</div>
</div>
</section>
<!-- Footer -->
<section id="footer">
<footer>
<div class="container-dark">
<div class="container-footer">
<div class="footer-icon-list">
<i class="fab fa-twitter footer-icon"></i>
<i class="fab fa-linkedin footer-icon"></i>
<i class="fab fa-github footer-icon"></i>
<i class="fab fa-dev footer-icon"></i>
<i class="fab fa-instagram footer-icon"></i>
</div>
</div>
</div>
</footer>
</section>
<script type="text/javascript" src="./js/hamburger.js"></script>
</body>
</html>
Step 2
Let's make our html look better and responsible by adding some CSS to ./css/style.css
html {
scroll-behavior: smooth;
overflow-x: hidden;
}
body {
font-family: "Open Sans", sans-serif;
margin: 0px;
background-color: rgb(51, 44, 56);
box-sizing: border-box;
overflow-x: hidden;
}
h1 {
padding: 0;
margin: 0;
}
h2 {
margin: 0;
padding: 0;
}
p {
margin: 0;
padding: 0;
}
.container-dark {
display: flex;
width: 100%;
justify-content: center;
}
.container-light {
display: flex;
width: 100%;
justify-content: center;
background-color: whitesmoke;
}
/* Hamburger button */
.hamburger-button {
display: none;
}
.hamburger-menu {
display: none;
}
/* Navigation bar */
.navigation-bar {
display: flex;
justify-content: center;
align-items: center;
width: 75%;
height: 10vh;
}
.navigation-bar > ul {
display: flex;
width: 100%;
list-style-type: none;
justify-content: space-between;
flex-direction: row;
padding: 0;
}
.navigation-bar > ul > li {
width: fit-content;
}
.navigation-bar > ul > li > a {
text-decoration: none;
color: whitesmoke;
font-weight: 700;
letter-spacing: 0.2rem;
}
.navigation-bar > ul > li > a:hover {
color: green;
transition: 0.75s;
cursor: pointer;
}
/* Home section */
.container-home {
display: flex;
width: 75%;
height: 90vh;
justify-content: center;
align-items: center;
font-size: 2rem;
font-weight: 700;
color: green;
}
/* About section */
.container-about {
display: flex;
width: 75%;
height: 20rem;
background-color: whitesmoke;
justify-content: center;
align-items: center;
font-size: 2rem;
font-weight: 700;
color: green;
}
/* Projects */
.container-projects {
display: flex;
width: 75%;
height: 20rem;
justify-content: center;
align-items: center;
font-size: 2rem;
font-weight: 700;
color: green;
}
/* Skills */
.container-skills {
display: flex;
width: 75%;
height: 20rem;
justify-content: center;
align-items: center;
font-size: 2rem;
font-weight: 700;
color: green;
}
/* Timeline */
.container-timeline {
display: flex;
width: 75%;
height: 20rem;
justify-content: center;
align-items: center;
font-size: 2rem;
font-weight: 700;
color: green;
}
/* Blog */
.container-blog {
display: flex;
width: 75%;
height: 20rem;
justify-content: center;
align-items: center;
font-size: 2rem;
font-weight: 700;
color: green;
}
/* Footer */
.container-footer {
display: flex;
width: 75%;
height: 20rem;
justify-content: center;
align-items: center;
font-size: 2rem;
font-weight: 700;
color: green;
}
.footer-icon-list {
font-size: 1.5rem;
color: whitesmoke;
margin-top: 2rem;
margin-bottom: 2rem;
letter-spacing: 1rem;
}
.footer-icon:hover {
color: green;
cursor: pointer;
transition: 0.75s;
}
/* Responsive */
/* For mobile large */
@media only screen and (max-width: 600px) {
.navigation-bar {
visibility: hidden;
}
li a.icon {
visibility: visible;
}
/* Home */
.container-home {
display: flex;
flex-direction: column;
width: 100%;
height: 20rem;
justify-content: center;
align-items: center;
margin-top: 0;
padding-top: 0;
}
/* About section */
.container-about {
display: flex;
height: auto;
width: 75%;
height: 20rem;
background-color: whitesmoke;
}
/* Projects */
.container-projects {
width: 100%;
}
/* Skills */
.container-skills {
width: 100%;
}
/* Timeline */
.container-timeline {
width: 60%;
}
/* Blog */
.container-blog {
width: 100%;
}
/* Footer */
.container-footer {
width: 100%;
}
/* Hamburger button */
.hamburger-button {
display: block;
font-size: 2rem;
color: green;
background-color: transparent;
border: none;
position: fixed;
left: 1rem;
top: 1rem;
z-index: 30;
}
.hamburger-menu {
display: none;
flex-direction: column;
justify-content: center;
align-items: center;
width: 100%;
height: 100vh;
padding: 0;
position: fixed;
left: 0;
top: 0;
z-index: 20;
background-color: rgb(51, 44, 56);
}
.hamburger-menu > ul {
display: flex;
flex-direction: column;
width: 100%;
list-style-type: none;
justify-content: center;
align-items: center;
padding: 0;
}
.hamburger-menu > ul > li {
width: fit-content;
margin: 1.5rem;
}
.hamburger-menu > ul > li > a {
text-decoration: none;
font-size: 2rem;
color: whitesmoke;
font-weight: 700;
letter-spacing: 0.2rem;
}
.hamburger-menu > ul > li > a:hover {
color: green;
transition: 0.75s;
cursor: pointer;
}
}
Step 3
Add the below code to ./js/hamburger.js
This is the code for handling the collapsible menu bar as well as toggling the hamburger button and close button.
function hamburgerMenu() {
// Toggle the side menu
let hamburgerMenu = document.querySelector(".hamburger-menu");
let menuStyle = getComputedStyle(hamburgerMenu);
if (menuStyle.display == "none") {
document.getElementById("ham-menu").style.display = "flex";
} else {
document.getElementById("ham-menu").style.display = "none";
}
// Exchange hamburger icon and close icon
let hamburgerIcon = document.querySelector("#ham-icon");
if (hamburgerIcon.classList.contains("fa-bars")) {
hamburgerIcon.classList.replace("fa-bars", "fa-times-circle");
return;
} else {
hamburgerIcon.classList.replace("fa-times-circle", "fa-bars");
return;
}
}
DONE!
Now you can open ./index.html
file with your web browser and inspect the responsive navigation menu that we have just built.
Happy coding!
Posted on September 30, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.