Header navigation

Header main navigation with links to other pages on the web site.

The header navigation contains links to other pages on the web site. It typically comes right after the logo and is rendered in a horizontal format.

The nav landmark is used to markup the main navigation, but to make it work properly for screen readers it requires an aria-label or aria-labelledby attribute.

  • Should be internationalized, as it will be read out loud to screen reader users
  • Avoid using the word "navigation" or "menu" as the label, this is redundant information since the screen reader will already read that from the nav element
  • Use short and descriptive names, since this is the main navigation usually the words "Main" or "Site" are used in this context

To highlight the current page, add aria-current="page" attribute to the link.

Don't forget to switch the icon on the current page to use the solid version of the icon.

<header class="flix-header flix-header--unfixed">
  <div class="flix-header__inner">
    <div class="flix-header-brand flix-header-brand--square">
      <a class="flix-header-brand__link" href="/">
        <img class="flix-header-brand__img" width="36" height="36" src="/img/logos/svg/honeycomb-white.svg" alt="Honeycomb Logo"/>
      </a>
    </div>
    
    <nav class="flix-header-nav" aria-label="Main">
      <ul class="flix-header-nav__list">
        <li class="flix-header-nav__item">
          <a class="flix-header-nav__link" aria-current="page" href="/">
            <i class="flix-icon flix-icon-home-solid" aria-hidden="true"></i>
            <span class="flix-header-nav__text">My bookings</span>
          </a>
        </li>
        <li class="flix-header-nav__item">
          <a class="flix-header-nav__link" href="/">
            <i class="flix-icon flix-icon-location-solid" aria-hidden="true"></i>
            <span class="flix-header-nav__text">Plan trip</span>
          </a>
        </li>
        <li class="flix-header-nav__item">
          <a class="flix-header-nav__link" href="/">
            <i class="flix-icon flix-icon-real-time" aria-hidden="true"></i>
            <span class="flix-header-nav__text">Real-time</span>
          </a>
        </li>
        <li class="flix-header-nav__item">
          <a class="flix-header-nav__link" href="/">
            <span class="flix-header-nav__text">About Us</span>
          </a>
        </li>
      </ul>
    </nav>
    
  </div>
</header>

To make dropdown sub navigation we use the same approach as the dropdown component, so you can rely on the dropdown plugin to handle the attributes and toggling.

The markup is simple:

  • Replace the flix-header-nav__link element to use a button instead, this will control the sub menu
  • Add a list with class name flix-header-nav-subnav that will contain the dropdown items and give it an id and add the hidden attribute to make it start hidden
    • flix-header-nav-subnav--left and,
    • flix-header-nav-subnav--right modifiers allow you to control the sub menu position when expanded.
  • To use the plugin, add data-dropdown={the-submenu-id} attribute to the button

The plugin will take care to add all the required ARIA attributes and toggle the dropdown list.

<header class="flix-header flix-header--unfixed">
  <div class="flix-header__inner">
    <div class="flix-header-brand flix-header-brand--square">
      <a class="flix-header-brand__link" href="/">
        <img class="flix-header-brand__img" width="36" height="36" src="/img/logos/svg/honeycomb-white.svg" alt="Honeycomb Logo"/>
      </a>
    </div>
    
    <nav class="flix-header-nav" aria-label="Main">
      <ul class="flix-header-nav__list">
        <li class="flix-header-nav__item">
          <a class="flix-header-nav__link" aria-current="page" href="/">
            <i class="flix-icon flix-icon-home-solid" aria-hidden="true"></i>
            <span class="flix-header-nav__text">My bookings</span>
          </a>
        </li>
        <li class="flix-header-nav__item">
          <button type="button" class="flix-header-nav__link" data-dropdown="flix-header-nav-subnav">
            <i class="flix-icon flix-icon-location-solid" aria-hidden="true"></i>
            <span class="flix-header-nav__text">Plan trip</span>
          </button>
          <ul id="flix-header-nav-subnav" class="flix-header-nav-subnav" hidden="">
            <li class="flix-header-nav-subnav__item">
              <a class="flix-header-nav-subnav__link" aria-current="page" href="/">
                <i class="flix-icon flix-icon-trip-solid" aria-hidden="true"></i>
                <span class="flix-header-nav-subnav__text">Route Network</span>
              </a>
            </li>
            <li class="flix-header-nav-subnav__item">
              <a class="flix-header-nav-subnav__link" href="/">
                <i class="flix-icon flix-icon-pin" aria-hidden="true"></i>
                <span class="flix-header-nav-subnav__text">Coach destination</span>
              </a>
            </li>
            <li class="flix-header-nav-subnav__item">
              <a class="flix-header-nav-subnav__link" href="/">
                <span class="flix-header-nav-subnav__text">Night buses</span>
              </a>
            </li>
          </ul>
        </li>
        <li class="flix-header-nav__item">
          <a class="flix-header-nav__link" href="/">
            <i class="flix-icon flix-icon-real-time" aria-hidden="true"></i>
            <span class="flix-header-nav__text">Real-time</span>
          </a>
        </li>
        <li class="flix-header-nav__item">
          <a class="flix-header-nav__link" href="/">
            <span class="flix-header-nav__text">About Us</span>
          </a>
        </li>
      </ul>
    </nav>
    
  </div>
</header>

Making it work without the plugin

The dropdown plugin ensures all the ARIA attributes are set correctly and handles toggling the menu correctly. If you don't want to use the plugin and prefers controlling the dropdown yourself, follow these instructions to ensure the dropdown works correctly and is accessible:

  • Add an id to the dropdown sub menu and the hidden attribute;
  • To the toggle button, add the following attributes:
    • aria-controls="{the-submenu-id}"
    • aria-haspopup="menu"
    • aria-expanded="false"

This will initiate the dropdown on a hidden state.

To show the dropdown, do:

  • Remove the hidden attribute from the dropdown list;
  • Switch the aria-expanded value from "false" to "true"

This will make the dropdown visible and navigable through tabbing.

The hidden attribute is important to hide the component from the tab order and the accessibility tree, effectively hiding it and making it impossible to be interacted with.

The aria-expanded attribute informs assistive technologies of the state of the component.

The CSS styles to show and hide the dropdown list are attached to the correct implementation of these attributes.

...
<li class="flix-header-nav__item">
  <button type="button" class="flix-header-nav__link" aria-controls="flix-header-nav-subnav" aria-haspopup="menu" aria-expanded="false">
    <i class="flix-icon flix-icon-location-solid" aria-hidden="true"></i>
    <span class="flix-header-nav__text">Plan trip</span>
  </button>
  <ul id="flix-header-nav-subnav" class="flix-header-subnav" hidden="">
    <li class="flix-header-subnav__item">
      <a class="flix-header-subnav__link" aria-current="page" href="/">
        <i class="flix-icon flix-icon-trip-solid" aria-hidden="true"></i>
        <span class="flix-header-nav__text">Route Network</span>
      </a>
    </li>
    <li class="flix-header-subnav__item">
      <a class="flix-header-subnav__link" href="/">
        <i class="flix-icon flix-icon-pin" aria-hidden="true"></i>
        <span class="flix-header-nav__text">Coach destination</span>
      </a>
    </li>
    <li class="flix-header-subnav__item">
      <a class="flix-header-subnav__link" href="/">
        <span class="flix-header-nav__text">Night buses</span>
      </a>
    </li>
  </ul>
</li>
...