CSS — Navigation Bars
The semantic skeleton
Navigation is a list of links — always:
<header class="site-header">
<a class="logo" href="/">codenatomy</a>
<nav aria-label="Main">
<ul class="menu">
<li><a href="/" class="active">Home</a></li>
<li><a href="/courses">Courses</a></li>
<li><a href="/about">About</a></li>
</ul>
</nav>
</header>
Screen readers announce "list, 3 items" before reading — orientation for free.
The full styling
.site-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 24px;
background: white;
box-shadow: 0 1px 3px rgba(0,0,0,.1);
}
.menu {
list-style: none;
display: flex;
gap: 4px;
margin: 0;
padding: 0;
}
.menu a {
display: block; /* full-cell click area */
padding: 10px 16px;
border-radius: 6px;
text-decoration: none;
color: #334155;
transition: background .2s, color .2s;
}
.menu a:hover { background: #f0fdfa; color: #0d9488; }
.menu a.active {
background: #0d9488;
color: white;
}
What it renders
(White bar: logo left, three rounded menu items right, teal pill marking the current page.)
Sticky header
.site-header {
position: sticky;
top: 0;
z-index: 100; /* above content, below modals */
}
Sticks on scroll for free (position lesson). Give the page breathing room if using fixed instead.
Active page indicator
Beyond color, an underline that slides:
.menu a.active::after {
content: "";
display: block;
height: 2px;
background: currentColor;
border-radius: 2px;
}
Set .active server-side or with one JS line comparing location.pathname.
Mobile: hamburger pattern
<button class="hamburger" aria-expanded="false" aria-controls="menu">
☰
</button>
@media (max-width: 700px) {
.menu {
display: none;
position: absolute;
top: 100%; left: 0; right: 0;
flex-direction: column;
background: white;
box-shadow: var(--shadow-2);
}
.menu.open { display: flex; }
}
const burger = document.querySelector(".hamburger");
burger.addEventListener("click", () => {
const open = menu.classList.toggle("open");
burger.setAttribute("aria-expanded", open);
});
(Under 700px the menu collapses into a toggleable dropdown panel.)
aria-expanded tells screen readers the state — two attributes, most of the accessibility won.
Dropdown menus in navs
.has-dropdown { position: relative; }
.dropdown {
display: none;
position: absolute;
top: 100%; left: 0;
min-width: 180px;
background: white;
box-shadow: var(--shadow-3);
border-radius: 8px;
}
.has-dropdown:hover .dropdown,
.has-dropdown:focus-within .dropdown {
display: block;
}
:focus-within keeps it open while keyboard users tab through items.
Checklist
-
<nav>+<ul>semantics - Block links (big touch targets ≥44px)
- Hover + focus-visible + active-page styles
-
aria-expandedon hamburger - Sticky z-index below modal scale
Mini Practice
- Build the header from scratch; verify all four link states.
- Make it sticky; add shadow only after scrolling (JS toggles a class).
- Mobile collapse with working aria-expanded.
- Underline slide-in on hover via ::after scaleX.
- Add a focus-within dropdown under "Courses".
Next: dropdowns →
Related Topics
Frequently Asked Questions about Navigation Bars
What is Navigation Bars in CSS?
Navigation Bars is a fundamental concept in CSS. This lesson explains it step by step with clear examples, making it easy for beginners to understand.
How do I learn Navigation Bars?
Start by reading the explanation above, then try the code examples. Practice by modifying the examples and experimenting with different values. Hands-on practice is the best way to learn Navigation Bars.
Why is Navigation Bars important in CSS?
Navigation Bars is essential for CSS development. Understanding this concept will help you write better code and solve real-world problems more effectively.