Code examples

Use semantic HTML

This semantic HTML contains all accessibility features by default.

<a href="#example-nav">Skip to example navigation</a>
<nav tabindex="-1" id="example-nav">
  <ul>
    <li><a href="/">Home</a></li>
    <li><a href="/about/">About</a></li>
    <li><a href="/contact/">Contact</a></li>
    <li><button aria-haspopup="true">Sign in</button></li>
  </ul>
</nav>
Skip to example navigation

Keep custom menus as simple as possible

Use semantic elements where possible.

<nav class="menu expander-group">
  <a class="home" href="/">
    Home
  </a>
  <button type="button"
          class="menu expander-toggle"
          aria-expanded="false"
          aria-haspopup="true">
    Menu
  </button>
  <ul class="expander-content">
    <li>
      <a href="/about/">About</a>
      <button type="button"
              class="subnav expander-toggle"
              aria-expanded="false"
              aria-haspopup="true">
        <span class="hidden">About</span>
      </button>
      <ul class="expander-content">
          <li>
            <a href="/history/">Our history</a>
          </li>
          <li>
            <a href="/values/">Our values</a>
          </li>
        </ul>
    </li>
    <li>
      <a href="/contact">Contact</a>
    </li>
    <li>
      <button>Sign in</button>
    </li>
  </ul>
</nav>

When you can’t use semantic HTML

This custom navigation requires extra attributes.

<div role="navigation">
  <ul>
    <li><a href="/">Website name</a></li>
    <li><a href="/about/">About</a></li>
    <li><a href="/contact/">Contact</a></li>
  <ul/>
</div>

Multiple navigation elements

When there is more than one navigation element, they should have a name.

<nav tabindex="-1" id="nav" aria-label="Main">
  <ul>
    <li><a href="/">Home</a></li>
    <li><a href="/about/">About</a></li>
    <li><a href="/contact/">Contact</a></li>
  <ul/>
</nav>

<h2 id="cat-heading">Categories</h2>
<nav id="cat-nav" aria-labelledby="#cat-heading">
  <ul>
    <li><a href="/alpha/">Alpha</a></li>
    <li><a href="/bravo/">Bravo</a></li>
    <li><a href="/charlie/">Charlie</a></li>
  <ul/>
</nav>

<footer>
  <nav aria-label="Site map">
    <ul>
      <li><a href="/">Home</a></li>
      <li><a href="/about/">About</a></li>
      <li><a href="/contact/">Contact</a></li>
    <ul/>
  </nav>
</footer>

Developer notes

Name

  • If there are multiple <nav> elements (site menu, pagination, categories) it may be helpful to name them
    • Use aria-label="Menu name" when there is not a visible nav title.
    • aria-describedby="menu-name-id" can be used when the nav title is a visible heading.

Role

  • Identifies itself as navigation
  • DO NOT add menu or option roles with arrow key event listeners unless you’re building an actual application like Gmail.

Focus

  • When skip links are used, add tabindex="-1" so that focus can move to the nav element, (not just bring it into view).