Building a responsive navbar with HTML and CSS is one of the first real challenges every front-end developer faces. Most tutorials online either rely on JavaScript, heavy frameworks like Bootstrap or Tailwind, or skip the explanation of why the code works. In this guide, we take a different approach: we build a clean, accessible, mobile-friendly navigation bar from scratch using only HTML and CSS, including a working hamburger menu toggle (no JavaScript required).
By the end of this tutorial, you will have a navbar you can copy, paste, and adapt to any project, whether it’s a portfolio, a landing page, or a full website.
Why Build a Navbar Without JavaScript or a Framework?
Frameworks are great, but they come with a cost: extra weight, extra dependencies, and code you don’t fully control. For beginners, learning the fundamentals first is what makes you a better developer in the long run.
- Lightweight: No external libraries means faster page loads.
- Educational: You understand every line of code.
- Customizable: Easy to tweak colors, spacing, and breakpoints.
- Accessible: A native checkbox toggle works without JavaScript enabled.

What We Are Building
Our navbar will have:
- A logo or brand name on the left.
- Navigation links on the right (desktop view).
- A hamburger icon that appears on mobile screens.
- A slide-down menu when the hamburger is clicked, powered entirely by the CSS
:checkedpseudo-class.
Step 1: The HTML Structure
Let’s start with clean, semantic HTML. Notice the use of the <nav> tag and a hidden checkbox that controls the menu state.
<nav class="navbar">
<div class="nav-container">
<a href="#" class="nav-logo">MyBrand</a>
<input type="checkbox" id="nav-toggle" class="nav-toggle">
<label for="nav-toggle" class="nav-hamburger">
<span></span>
<span></span>
<span></span>
</label>
<ul class="nav-menu">
<li><a href="#home">Home</a></li>
<li><a href="#about">About</a></li>
<li><a href="#services">Services</a></li>
<li><a href="#contact">Contact</a></li>
</ul>
</div>
</nav>
Why a Hidden Checkbox?
The checkbox hack is a classic CSS trick. By pairing a hidden <input type="checkbox"> with a <label>, we can detect clicks and toggle styles using only CSS, no JavaScript needed.
Step 2: The Base CSS
Now let’s style the navbar. We start with a reset and the desktop layout.
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Segoe UI', Arial, sans-serif;
}
.navbar {
background-color: #1f2937;
padding: 1rem 2rem;
position: sticky;
top: 0;
z-index: 100;
}
.nav-container {
max-width: 1200px;
margin: 0 auto;
display: flex;
justify-content: space-between;
align-items: center;
}
.nav-logo {
color: #fff;
font-size: 1.5rem;
font-weight: bold;
text-decoration: none;
}
.nav-menu {
display: flex;
list-style: none;
gap: 2rem;
}
.nav-menu a {
color: #f3f4f6;
text-decoration: none;
font-size: 1rem;
transition: color 0.2s ease;
}
.nav-menu a:hover {
color: #60a5fa;
}
.nav-toggle,
.nav-hamburger {
display: none;
}

Step 3: The Hamburger Icon
The hamburger is just three <span> bars stacked vertically. We hide it on desktop and show it on mobile.
.nav-hamburger {
flex-direction: column;
justify-content: space-between;
width: 28px;
height: 22px;
cursor: pointer;
}
.nav-hamburger span {
display: block;
height: 3px;
width: 100%;
background-color: #fff;
border-radius: 2px;
transition: all 0.3s ease;
}
Step 4: Mobile Styles with Media Queries
Below 768px, we hide the menu, display the hamburger, and use the :checked selector to slide the menu in when the user taps the icon.
@media (max-width: 768px) {
.nav-hamburger {
display: flex;
}
.nav-menu {
position: absolute;
top: 100%;
left: 0;
right: 0;
flex-direction: column;
background-color: #1f2937;
padding: 1rem 2rem;
gap: 1rem;
max-height: 0;
overflow: hidden;
transition: max-height 0.3s ease;
}
.nav-toggle:checked ~ .nav-menu {
max-height: 400px;
}
.nav-toggle:checked ~ .nav-hamburger span:nth-child(1) {
transform: translateY(9px) rotate(45deg);
}
.nav-toggle:checked ~ .nav-hamburger span:nth-child(2) {
opacity: 0;
}
.nav-toggle:checked ~ .nav-hamburger span:nth-child(3) {
transform: translateY(-9px) rotate(-45deg);
}
}
The hamburger animates into a clean X icon when the menu is open, giving users clear feedback.
Step 5: Test It Across Devices
Open your browser DevTools and toggle device mode. You should see:
| Screen Width | Behavior |
|---|---|
| Above 768px | Horizontal menu, no hamburger |
| 768px and below | Hamburger visible, menu collapses |
| Hamburger clicked | Menu slides down, icon turns into X |

Bonus: Common Improvements
Once your basic navbar works, consider these upgrades:
- Dropdown submenus: Add nested
<ul>elements with:hoverstyling. - Sticky header on scroll: Already done with
position: sticky. - Dark and light mode: Use CSS variables for color theming.
- Accessibility: Add
aria-labelto the hamburger label and make sure focus states are visible. - Smooth scrolling: Add
scroll-behavior: smoothto yourhtmlelement.
Best Practices for a Production-Ready Navbar
- Always use semantic tags like
<nav>and<ul>for navigation. - Keep your breakpoint consistent with the rest of your site (768px or 992px are common).
- Test keyboard navigation: users should be able to tab through links.
- Avoid fixed pixel widths on the menu container so it adapts to content.
- Lazy-load only what’s needed. A pure CSS navbar adds zero KB of JavaScript.
Final Thoughts
You now have a fully functional responsive navbar built with HTML and CSS, no frameworks, no JavaScript, and no bloat. This pattern is reliable, fast, and easy to customize. Use it as a starting point and build on top of it as your project grows.
At AHT Design, we believe that mastering the fundamentals is what separates good developers from great ones. A clean navbar is a small detail, but it sets the tone for the entire user experience.
Frequently Asked Questions
Can I build a responsive navbar without JavaScript?
Yes. Using the CSS checkbox hack with the :checked pseudo-class, you can toggle a mobile menu open and closed without writing a single line of JavaScript.
What is the best breakpoint for a mobile navbar?
768px is the most common breakpoint, matching the typical tablet portrait width. However, you can adjust it based on your design and target audience. 992px is also popular for content-heavy sites.
Should I use Flexbox or Grid for the navbar?
Flexbox is generally the better choice for navbars because it handles one-dimensional layouts (a single row of items) with less effort. Grid is more suited for two-dimensional page layouts.
How do I make my navbar accessible?
Add proper aria-label attributes, ensure keyboard focus is visible, use semantic HTML, and make sure color contrast meets WCAG standards. The hamburger button should announce its state to screen readers.
Can I add a dropdown menu to this navbar?
Absolutely. Nest a <ul> inside one of the <li> elements and show it on :hover for desktop or on :focus-within for keyboard users. The same checkbox hack also works for mobile dropdowns.




