Lesson 21 / Navigation

Site Navigation

Time
55 min
Type
Reading + Interactive
Level
Intermediate
Use
Core

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 GoalNeeded LinkPriorityBest Location
Understand the siteHome or brand linkHighMain navigation
Browse work or productsWork, Shop, or ProjectsHighMain navigation
Learn about the person or organizationAboutMediumMain or footer navigation
Get help or contact someoneContact or SupportHighMain, utility, or footer navigation
Find policies or social linksPrivacy, Terms, social linksLowFooter navigation
Move within a long sectionSection links or table of contentsContextualLocal navigation

Navigation Types

TypeUse ForExample
Main navigationPrimary site sectionsHome, Work, About, Contact
Footer navigationSecondary links and repeated important linksPrivacy, Resources, Social
Utility navigationAccount, search, language, or support linksLog in, Search, Help
Breadcrumb navigationShowing location in a hierarchyHome / Lessons / Site Navigation
Local navigationMoving within a section or pageLesson table of contents
PaginationMoving through ordered setsPrevious, Next, page numbers
Skip linkLetting keyboard users bypass repeated navigationSkip 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 here or Learn more in 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-visible styles for links and buttons.
  • Keep labels clear and predictable.
  • Test with Tab, Shift + Tab, Enter, Space, and Escape if 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-expanded update when the menu opens and closes?
  • Does the current page link use aria-current="page"?
  • Does the skip link appear when focused?

Common Mistakes

MistakeWhy It HurtsFix
Too many top-level linksThe main navigation becomes hard to scanPrioritize primary user goals and move secondary links elsewhere.
Vague labelsUsers cannot predict where links goUse clear destination-based labels.
Navigation only works on hoverKeyboard and touch users may be blockedSupport click, keyboard, and touch behavior.
No focus stylesKeyboard users lose track of locationAdd strong :focus-visible styles.
Missing current page indicatorUsers may not know where they areUse aria-current="page" and a visible active style.
Fixed header covers contentHeadings and anchor targets can be hiddenUse position: sticky when possible and add scroll-padding-top.
Menu toggle is not a buttonInteraction semantics are wrongUse 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 nav with 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-expanded and aria-controls.
  • Add clear :focus-visible styles.
  • Test the navigation with only the keyboard.