How to Create a Responsive Navigation Menu with HTML and CSS

How to create a responsive navigation menu. a wide shot of a futuristic

A navigation menu is one of the first things visitors interact with, and it needs to work just as well on a phone as it does on a widescreen monitor. In this guide, we’ll build a responsive navigation bar from scratch — a horizontal menu on desktop that collapses into a mobile-friendly hamburger toggle on smaller screens — using only HTML, CSS, and a touch of vanilla JavaScript.

What We’re Building

Before diving into code, here’s what the finished menu will do:

  • Display a horizontal navigation bar on desktop and tablet screens
  • Collapse into a hamburger icon on mobile
  • Toggle the mobile menu open and closed on click
  • Highlight the active page link
  • Work without any external libraries or frameworks

Step 1: The HTML Structure

Start with a semantic <nav> element containing your logo, a list of links, and a hamburger button for mobile.

<nav class="navbar">
  <div class="navbar-logo">
    <a href="/">HTMLFive Can</a>
  </div>

  <ul class="nav-links" id="navLinks">
    <li><a href="/" class="active">Home</a></li>
    <li><a href="/about/">About</a></li>
    <li><a href="/our-mission/">Our Mission</a></li>
    <li><a href="/blog/">Blog</a></li>
    <li><a href="/contact/">Contact</a></li>
  </ul>

  <button class="hamburger" id="hamburger" aria-label="Toggle menu">
    <span></span>
    <span></span>
    <span></span>
  </button>
</nav>

Step 2: Base CSS for the Desktop Layout

Style the navbar as a flex container so the logo sits on one side and the links on the other.

* {
  box-sizing: border-box;
}

.navbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 1rem 2rem;
  background-color: #1a1a2e;
}

.navbar-logo a {
  color: #ffffff;
  font-size: 1.25rem;
  font-weight: 700;
  text-decoration: none;
}

.nav-links {
  display: flex;
  list-style: none;
  gap: 2rem;
  margin: 0;
  padding: 0;
}

.nav-links a {
  color: #e0e0e0;
  text-decoration: none;
  font-size: 0.95rem;
  transition: color 0.2s ease;
}

.nav-links a:hover,
.nav-links a.active {
  color: #4f9dff;
}

.hamburger {
  display: none;
  flex-direction: column;
  gap: 5px;
  background: none;
  border: none;
  cursor: pointer;
  padding: 0;
}

.hamburger span {
  width: 25px;
  height: 3px;
  background-color: #ffffff;
  border-radius: 2px;
}

Step 3: Adding the Mobile Breakpoint

Hide the horizontal menu and show the hamburger icon below a set width, typically 768px.

@media (max-width: 768px) {
  .hamburger {
    display: flex;
  }

  .nav-links {
    position: absolute;
    top: 60px;
    left: 0;
    right: 0;
    flex-direction: column;
    background-color: #1a1a2e;
    text-align: center;
    gap: 0;
    max-height: 0;
    overflow: hidden;
    transition: max-height 0.3s ease;
  }

  .nav-links.open {
    max-height: 300px;
  }

  .nav-links li {
    padding: 1rem 0;
    border-top: 1px solid rgba(255, 255, 255, 0.1);
  }
}

Step 4: Making the Hamburger Functional with JavaScript

The CSS handles the visual collapse, but you need a small script to toggle the open class when the hamburger is clicked.

<script>
  const hamburger = document.getElementById('hamburger');
  const navLinks = document.getElementById('navLinks');

  hamburger.addEventListener('click', () => {
    navLinks.classList.toggle('open');
  });
</script>

Place this right before the closing </body> tag.

Best Practices to Keep in Mind

  • Use aria-label on the hamburger button — screen readers need a text description since the icon itself has no visible text
  • Close the menu after a link is clicked — on mobile, add a click listener on each link that removes the open class, so the menu doesn’t stay open after navigation
  • Pick a sensible breakpoint — 768px works for most sites, but check your actual traffic’s device breakdown before assuming
  • Avoid display: none for the hamburger animation — using max-height with a transition (as shown above) gives a smoother open/close effect than an instant show/hide
  • Test with keyboard navigation — make sure links are reachable via Tab and the menu is usable without a mouse

Common Mistakes to Avoid

  • Forgetting box-sizing: border-box, which throws off padding calculations on smaller screens
  • Hardcoding pixel widths instead of using flexible units, causing overflow on narrow devices
  • Skipping the active link style, leaving visitors unsure which page they’re currently on
  • Not testing the toggle behavior on an actual mobile device, only in a resized desktop browser window

Wrapping Up

A responsive navigation menu doesn’t need a framework or a plugin — a semantic HTML structure, a flexbox layout, one media query, and a few lines of JavaScript are enough to make it work smoothly across devices. From here, you can extend this pattern with dropdown submenus, a sticky header on scroll, or a search bar integrated into the nav.

Running into an issue with your menu not collapsing correctly, or want help adapting this to your specific site layout? Get in touch with our team and we’ll help you debug it.

Leave a Reply

Your email address will not be published. Required fields are marked *