How to Build a Responsive Navigation Bar with HTML, CSS & JavaScript (2026) | GrowWP

How to Build a Responsive Navigation Bar with HTML, CSS & JavaScript (2026)

Every website needs a navigation bar — it's the first thing visitors see and the backbone of your site's UX. In this step-by-step guide, you'll build a fully responsive navbar from scratch using only HTML, CSS, and JavaScript. No frameworks, no libraries — just clean, beginner-friendly code that actually works on mobile.

What is a Navigation Bar?

A navigation bar (navbar) is the row of links at the top of a webpage that helps users move between sections or pages. Think of it like the menu at a restaurant — without it, visitors don't know where to go.

A well-built navbar should:

  • Work on all screen sizes (desktop, tablet, mobile)
  • Show a hamburger menu (☰) on small screens
  • Be easy to read and click/tap
  • Load fast — no heavy libraries needed
💡

Why this matters for WordPress users: Even if you use Elementor or a theme, understanding how a navbar works in raw HTML/CSS gives you full control when you need to customize it — and it's a must-know skill for web developers.

What You'll Need

You don't need to install anything. Just create one file called index.html on your computer and open it in your browser. That's it.

ToolPurposeFree?
VS CodeCode editor to write HTML/CSS/JS✅ Yes
Any browserTo preview your navbar live✅ Yes
Basic HTML knowledgeTags like <nav>, <ul>, <li>✅ Free to learn
1

HTML Structure

First, let's build the skeleton. We'll use the <nav> HTML5 tag — it's semantic, which means search engines and screen readers understand it's a navigation element.

HTML
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>My Responsive Navbar</title>
  <link rel="stylesheet" href="style.css" />
</head>
<body>

  <nav class="navbar">
    <div class="nav-container">

      <!-- Logo -->
      <a href="#" class="nav-logo">GrowWP</a>

      <!-- Navigation Links -->
      <ul class="nav-links" id="navLinks">
        <li><a href="#" class="active">Home</a></li>
        <li><a href="#">Blogs</a></li>
        <li><a href="#">Tools</a></li>
        <li><a href="#">About</a></li>
        <li><a href="#">Contact</a></li>
      </ul>

      <!-- Hamburger Button (visible only on mobile) -->
      <button class="hamburger" id="hamburger" aria-label="Toggle menu">
        <span></span>
        <span></span>
        <span></span>
      </button>

    </div>
  </nav>

  <script src="script.js"></script>
</body>
</html>

Pro Tip: Always add aria-label="Toggle menu" to your hamburger button. This helps visually impaired users who use screen readers understand what the button does.

2

CSS Styling (Desktop First)

Now create a file called style.css and add the following. We'll style the desktop view first, then handle mobile with media queries.

CSS
/* ── Reset & Base ── */
* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

body {
  font-family: 'Inter', sans-serif;
}

/* ── Navbar ── */
.navbar {
  background-color: #1e293b;
  position: sticky;
  top: 0;
  z-index: 1000;
  box-shadow: 0 2px 12px rgba(0,0,0,0.2);
}

.nav-container {
  max-width: 1100px;
  margin: 0 auto;
  padding: 0 24px;
  height: 60px;
  display: flex;
  align-items: center;
  justify-content: space-between;
}

/* ── Logo ── */
.nav-logo {
  color: #ffffff;
  font-size: 1.3rem;
  font-weight: 700;
  text-decoration: none;
  letter-spacing: -0.5px;
}

/* ── Nav Links ── */
.nav-links {
  list-style: none;
  display: flex;
  gap: 4px;
}

.nav-links a {
  color: #cbd5e1;
  text-decoration: none;
  font-size: 0.9rem;
  font-weight: 500;
  padding: 6px 14px;
  border-radius: 6px;
  transition: background 0.2s, color 0.2s;
}

.nav-links a:hover,
.nav-links a.active {
  background: #2563eb;
  color: #ffffff;
}

/* ── Hamburger (hidden on desktop) ── */
.hamburger {
  display: none;
  flex-direction: column;
  gap: 5px;
  cursor: pointer;
  background: none;
  border: none;
  padding: 6px;
}

.hamburger span {
  display: block;
  width: 24px;
  height: 2px;
  background: #cbd5e1;
  border-radius: 2px;
  transition: all 0.3s ease;
}
3

Making It Responsive with Media Queries

This is where the magic happens. Below 768px screen width, we hide the nav links and show the hamburger button instead. When clicked, JavaScript will toggle a class to show/hide the menu.

CSS — Add to style.css
/* ── Mobile Styles ── */
@media (max-width: 768px) {

  .hamburger {
    display: flex; /* Show hamburger on mobile */
  }

  .nav-links {
    display: none; /* Hide links by default */
    position: absolute;
    top: 60px;
    left: 0;
    right: 0;
    background: #1e293b;
    flex-direction: column;
    padding: 12px 24px 20px;
    gap: 4px;
    border-top: 1px solid #334155;
  }

  .nav-links.open {
    display: flex; /* Show when JS adds .open class */
  }

  .nav-links a {
    padding: 10px 12px;
    font-size: 0.95rem;
  }

  /* ── Hamburger → X Animation ── */
  .hamburger.open span:nth-child(1) {
    transform: translateY(7px) rotate(45deg);
  }
  .hamburger.open span:nth-child(2) {
    opacity: 0;
  }
  .hamburger.open span:nth-child(3) {
    transform: translateY(-7px) rotate(-45deg);
  }
}
⚠️

Remember: The .navbar must have position: sticky or position: relative for the mobile dropdown to position correctly using position: absolute.

4

JavaScript for the Hamburger Menu

Now create a file called script.js. This is a very small script — only 10 lines — that toggles the .open class on the hamburger button and nav links when the button is clicked.

JavaScript
// Select the hamburger button and nav links
const hamburger = document.getElementById('hamburger');
const navLinks = document.getElementById('navLinks');

// Toggle menu open/closed on button click
hamburger.addEventListener('click', () => {
  hamburger.classList.toggle('open');
  navLinks.classList.toggle('open');
});

// Close menu when a nav link is clicked (good for single-page sites)
navLinks.querySelectorAll('a').forEach(link => {
  link.addEventListener('click', () => {
    hamburger.classList.remove('open');
    navLinks.classList.remove('open');
  });
});

That's it! Three filesindex.html, style.css, script.js — and you have a fully working responsive navbar.

Live Demo Preview

Here's how your navbar will look. Try resizing your browser window to see it go mobile:

🔴 Live Preview

Bonus: Active Link Highlight with JavaScript

Want the current page link to always be highlighted? Add this snippet to your script.js — it automatically adds the .active class to whichever link matches the current page URL.

JavaScript — Bonus
// Auto-highlight the active nav link based on current page
const currentPage = window.location.href;

document.querySelectorAll('.nav-links a').forEach(link => {
  if (currentPage.includes(link.getAttribute('href'))) {
    link.classList.add('active');
  }
});

Complete Final Code (All-in-One)

If you prefer a single file instead of three separate files, here's the complete self-contained version:

HTML — Complete Single File
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Responsive Navbar</title>
  <style>
    * { box-sizing: border-box; margin: 0; padding: 0; }
    body { font-family: sans-serif; }
    .navbar { background: #1e293b; position: sticky; top: 0; z-index: 1000; }
    .nav-container {
      max-width: 1100px; margin: 0 auto; padding: 0 24px;
      height: 60px; display: flex; align-items: center; justify-content: space-between;
    }
    .nav-logo { color: #fff; font-size: 1.3rem; font-weight: 700; text-decoration: none; }
    .nav-links { list-style: none; display: flex; gap: 4px; }
    .nav-links a {
      color: #cbd5e1; text-decoration: none; font-size: 0.9rem;
      font-weight: 500; padding: 6px 14px; border-radius: 6px;
      transition: background 0.2s, color 0.2s;
    }
    .nav-links a:hover, .nav-links a.active { background: #2563eb; color: #fff; }
    .hamburger {
      display: none; flex-direction: column; gap: 5px;
      cursor: pointer; background: none; border: none; padding: 6px;
    }
    .hamburger span {
      display: block; width: 24px; height: 2px;
      background: #cbd5e1; border-radius: 2px; transition: all 0.3s ease;
    }
    @media (max-width: 768px) {
      .hamburger { display: flex; }
      .nav-links {
        display: none; position: absolute; top: 60px; left: 0; right: 0;
        background: #1e293b; flex-direction: column;
        padding: 12px 24px 20px; gap: 4px; border-top: 1px solid #334155;
      }
      .nav-links.open { display: flex; }
      .nav-links a { padding: 10px 12px; font-size: 0.95rem; }
      .hamburger.open span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
      .hamburger.open span:nth-child(2) { opacity: 0; }
      .hamburger.open span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }
    }
  </style>
</head>
<body>
  <nav class="navbar">
    <div class="nav-container">
      <a href="#" class="nav-logo">GrowWP</a>
      <ul class="nav-links" id="navLinks">
        <li><a href="#" class="active">Home</a></li>
        <li><a href="#">Blogs</a></li>
        <li><a href="#">Tools</a></li>
        <li><a href="#">About</a></li>
        <li><a href="#">Contact</a></li>
      </ul>
      <button class="hamburger" id="hamburger" aria-label="Toggle menu">
        <span></span><span></span><span></span>
      </button>
    </div>
  </nav>
  <script>
    const hamburger = document.getElementById('hamburger');
    const navLinks = document.getElementById('navLinks');
    hamburger.addEventListener('click', () => {
      hamburger.classList.toggle('open');
      navLinks.classList.toggle('open');
    });
    navLinks.querySelectorAll('a').forEach(link => {
      link.addEventListener('click', () => {
        hamburger.classList.remove('open');
        navLinks.classList.remove('open');
      });
    });
  </script>
</body>
</html>

Conclusion

Congratulations! 🎉 You just built a fully responsive navigation bar from scratch using only HTML, CSS, and JavaScript — no frameworks, no external libraries.

Here's a quick recap of what you learned:

  • How to use the semantic <nav> tag
  • How to style a desktop navbar with Flexbox
  • How to use CSS Media Queries to make it mobile-friendly
  • How to build a hamburger menu animation with pure CSS
  • How to use JavaScript classList.toggle() to open/close the menu

These are foundational skills every web developer should know. Once you're comfortable here, you can take this further with dropdown menus, sticky scroll effects, or even integrating this into your WordPress theme's header.php.

🚀

Next Step: Try adding a dropdown submenu to one of the nav links. It's the natural next challenge after mastering this! Check GrowWP's upcoming tutorial on CSS Dropdowns.

📥 Want More Free Web Dev Guides?

Download our free WordPress + Web Development PDF cheatsheets — no signup needed.

Get Free PDFs →
A
Akash Vishwakarma

WordPress developer with 3+ years of experience. Founder of GrowWP.in — a learning hub for beginners who want to build real websites without the fluff. Writes about WordPress, HTML/CSS/JS, SEO, and site monetization.

Latest Articles

Explore our latest blog posts, tutorials, SEO tips and WordPress guides.