Lesson 21 / Navigation
Site Navigation
Design clear, consistent, accessible navigation systems that help users understand where they are and where they can go next.
Course Role
Core
Part of the main course path. Prioritize this before moving to optional polish or deeper references.
Teacher Notes / In-Class Use
Demo Live
- Use the navigation lab to show semantic nav, current page state, skip links, visible focus, and menu button state.
- Tab through the sample navigation so keyboard access is visible, not theoretical.
Try In Class
- Have students mark up a primary nav with a nav element and meaningful link labels.
- Ask students to add or verify a visible focus state for every navigation link.
Submit Or Check
- Current page state should be visible and, when appropriate, exposed with aria-current.
- Mobile menus should use a real button with aria-expanded and aria-controls.
Watch For
- Divs or spans acting like menu buttons.
- Navigation labels that are visually clever but unclear out of context.
Learning Goals
- Plan navigation around user goals, page priority, and site structure
- Build semantic navigation with `nav`, links, skip links, breadcrumbs, and current-page states
- Create responsive navigation behavior with accessible buttons, focus styles, and keyboard testing
Interactive Demo
How to use this demo.
Use the demo as a small lab. Change one thing, observe the result, then connect it back to your own project.
What To Try
- Toggle semantic navigation, current page state, focus visibility, skip link, and mobile button options.
- Use Tab to move through the preview after changing settings.
What Changes
- The checklist and code sample update with each navigation choice.
- The preview shows how small markup choices affect usability.
What To Notice
- Navigation must work visually, semantically, and with the keyboard.
- Mobile menus need real button state, not only a visual icon.
Apply It
- Review your project navigation and confirm the current page and focus states are clear.
This demo uses extra JavaScript for teaching. The code sample shows the pattern to practice. View full demo source.
Introduction
Navigation helps users understand where they are, where they can go, and how to complete tasks. Good navigation makes a site feel predictable instead of confusing.
Start with clear links and semantic HTML. Add CSS for layout and states. Use JavaScript only when the navigation needs interaction, such as opening a mobile menu.
What Good Navigation Answers
- Where am I?
- What can I do here?
- Where can I go next?
- How do I get back to a broader section or the homepage?
Navigation Planning
Before building a menu, decide which links matter most. Not every page belongs in the main navigation.
| User Goal | Needed Link | Priority | Best Location |
|---|---|---|---|
| Understand the site | Home or brand link | High | Main navigation |
| Browse work or products | Work, Shop, or Projects | High | Main navigation |
| Learn about the person or organization | About | Medium | Main or footer navigation |
| Get help or contact someone | Contact or Support | High | Main, utility, or footer navigation |
| Find policies or social links | Privacy, Terms, social links | Low | Footer navigation |
| Move within a long section | Section links or table of contents | Contextual | Local navigation |
Navigation Types
| Type | Use For | Example |
|---|---|---|
| Main navigation | Primary site sections | Home, Work, About, Contact |
| Footer navigation | Secondary links and repeated important links | Privacy, Resources, Social |
| Utility navigation | Account, search, language, or support links | Log in, Search, Help |
| Breadcrumb navigation | Showing location in a hierarchy | Home / Lessons / Site Navigation |
| Local navigation | Moving within a section or page | Lesson table of contents |
| Pagination | Moving through ordered sets | Previous, Next, page numbers |
| Skip link | Letting keyboard users bypass repeated navigation | Skip to main content |
Semantic Main Navigation
Use nav for navigation regions, ul and li for lists of links, and a for destinations. Add aria-label when the page has more than one navigation region.
<nav class="site-nav" aria-label="Main navigation">
<ul>
<li><a href="/">Home</a></li>
<li><a href="/work/" aria-current="page">Work</a></li>
<li><a href="/about/">About</a></li>
<li><a href="/contact/">Contact</a></li>
</ul>
</nav> Current Page State
aria-current="page" tells assistive technology which navigation link represents the current page. It can also be used as a styling hook.
.site-nav a[aria-current="page"] {
font-weight: 700;
text-decoration-thickness: 0.18em;
} Link Labels
- Use labels that match the destination.
- Keep main navigation labels short.
- Avoid vague labels such as
Click hereorLearn morein navigation. - Do not overload the main navigation with every page on the site.
- Use footer, utility, and contextual navigation for lower-priority links.
Skip Links
A skip link lets keyboard users jump past repeated navigation and go straight to the main content.
<a class="skip-link" href="#main-content">Skip to main content</a>
<main id="main-content">
<h1>Site Navigation</h1>
</main> Skip Link CSS
.skip-link {
position: absolute;
inset-block-start: 0.5rem;
inset-inline-start: 0.5rem;
transform: translateY(-150%);
transition: transform 160ms ease;
}
.skip-link:focus {
transform: translateY(0);
} Breadcrumb Navigation
Breadcrumbs help users understand where the current page lives in the site hierarchy. They are especially useful on larger sites with nested sections.
<nav aria-label="Breadcrumb">
<ol class="breadcrumbs">
<li><a href="/">Home</a></li>
<li><a href="/lessons/">Lessons</a></li>
<li aria-current="page">Site Navigation</li>
</ol>
</nav> Responsive Navigation Markup
A responsive menu toggle should be a real button, not a link or a clickable div. Use aria-expanded and aria-controls to connect the button to the menu it controls.
<button class="nav-toggle" aria-expanded="false" aria-controls="main-nav">
Menu
</button>
<nav id="main-nav" class="site-nav" aria-label="Main navigation">
<ul>
<li><a href="/">Home</a></li>
<li><a href="/work/">Work</a></li>
<li><a href="/about/">About</a></li>
<li><a href="/contact/">Contact</a></li>
</ul>
</nav> Responsive Navigation CSS
The closed menu can be hidden by default on small screens, then revealed when JavaScript adds an open class.
.site-nav ul {
display: flex;
gap: 1rem;
list-style: none;
margin: 0;
padding: 0;
}
.nav-toggle {
display: none;
}
@media (max-width: 48rem) {
.nav-toggle {
display: inline-flex;
}
.site-nav:not(.is-open) {
display: none;
}
.site-nav ul {
flex-direction: column;
}
} Responsive Navigation JavaScript
JavaScript is needed only for the interactive toggle. The links themselves should remain normal links.
const toggleButton = document.querySelector('.nav-toggle');
const nav = document.querySelector('#main-nav');
toggleButton.addEventListener('click', () => {
const isOpen = nav.classList.toggle('is-open');
toggleButton.setAttribute('aria-expanded', String(isOpen));
}); Focus Styles
Visible focus styles help keyboard users see which link or button is active. Do not remove outlines without replacing them with a clear focus style.
.site-nav a:focus-visible,
.nav-toggle:focus-visible {
outline: 3px solid currentColor;
outline-offset: 0.25rem;
} Sticky Navigation
Use position: sticky when the navigation should stay near the top after the user scrolls to it. It is usually easier to manage than position: fixed because it remains in normal flow until it sticks.
scroll-padding-top helps anchor links avoid being hidden behind a sticky header.
.site-header {
position: sticky;
top: 0;
z-index: 20;
}
html {
scroll-padding-top: 5rem;
} Smooth Scrolling
Smooth scrolling can help same-page navigation feel connected, but it should respect reduced-motion preferences.
html {
scroll-behavior: smooth;
}
@media (prefers-reduced-motion: reduce) {
html {
scroll-behavior: auto;
}
} Dropdown and Mega Menu Accessibility
- Do not rely only on hover. Menus must work with keyboard and touch input.
- Use visible
:focus-visiblestyles for links and buttons. - Keep labels clear and predictable.
- Test with
Tab,Shift + Tab,Enter,Space, andEscapeif the menu can close. - Mega menus are best for large sites with clear categories, not small sites with only a few links.
Keyboard Testing Checklist
- Can you reach every navigation link with
Tab? - Can you see where focus is at all times?
- Can you open and close the responsive menu with the keyboard?
- Does
aria-expandedupdate when the menu opens and closes? - Does the current page link use
aria-current="page"? - Does the skip link appear when focused?
Common Mistakes
| Mistake | Why It Hurts | Fix |
|---|---|---|
| Too many top-level links | The main navigation becomes hard to scan | Prioritize primary user goals and move secondary links elsewhere. |
| Vague labels | Users cannot predict where links go | Use clear destination-based labels. |
| Navigation only works on hover | Keyboard and touch users may be blocked | Support click, keyboard, and touch behavior. |
| No focus styles | Keyboard users lose track of location | Add strong :focus-visible styles. |
| Missing current page indicator | Users may not know where they are | Use aria-current="page" and a visible active style. |
| Fixed header covers content | Headings and anchor targets can be hidden | Use position: sticky when possible and add scroll-padding-top. |
Menu toggle is not a button | Interaction semantics are wrong | Use a real button with aria-expanded and aria-controls. |
Checkpoint
Before moving on, make sure these feel true.
- I can build navigation with semantic HTML and clear link labels.
- I can show the current page state visually and semantically.
- I can test navigation with Tab, Shift+Tab, and Enter.
Project Connection
This lesson supports current class projects.
Practice
- Write a navigation plan for a small sitemap with main, footer, and utility links.
- Build a semantic
navwith at least four links. - Add
aria-current="page"to the current page link. - Add a skip link that appears on focus.
- Build a responsive menu toggle with
aria-expandedandaria-controls. - Add clear
:focus-visiblestyles. - Test the navigation with only the keyboard.