"The power of web is in its universality. Access by everyone regardless of disability is an essential aspect" ~ Tim Berners Lee

Accessible Dropdown Navigation :

What are dropdown navigations? They look similar to a box of options hanging down from the NavBar. You often get to see such navigations on websites you browse regularly. Hence, it is very important to make these accessible because they are mostly located at the topmost level of any website.

The first and foremost step to build accessible components is to start using Semantic HTML. We often ignore this step because of our covenience but this is NOT recommended.

So let me break down each of the components of the accessible navigation and start building it.

  1. The wrapper around the navigation should always be the semantic <nav> HTML tag.
  2. Navigation schema is composed of a set of links since links are focusable. It should be provided as a nested list of links.
  3. Attach aria attributes to the navigation for the assistive information when using screen readers.

Let us start CODING !!

<nav role="menu">
  <ul class="menu">
    <li class="menu_item">
      <a href="/about" class="menu_link">
        About
      </a>
      <ul class="submenu">
        <li class="submenu_item">
          <a class="submenu__link" href="/about/journey">
            Journey
          </a>
        </li>
        <li class="submenu_item">
          <a class="submenu__link" href="/about/team">
            Team
          </a>
        </li>
      </ul>
    </li>
    <li class="menu_item">
      <a href="/updates" class="menu_link">
        Updates
      </a>
      <ul class="submenu">
        <li class="submenu_item">
          <a class="submenu__link" href="/updates/blog">
            Blog
          </a>
        </li>
        <li class="submenu_item">
          <a class="submenu__link" href="/updates/press">
            Press
          </a>
        </li>
      </ul>
    </li>
    <li class="menu_item">
      <a href="/contact" class="menu_link">
        Contact
      </a>
    </li>
  </ul>
</nav>

The thing to note here is the WEB by default is always accessible. We often rupture the accessibility by using fancy styling and design. In this case, since all the anchor tags are focusable, the basic HTML skeleton of the navigation bar given above in itself is accessible. Something similar to this.

pure html navgation

However, we obviously won't like navigation something like this so let us just style it up. For the submenu, I have used visually-hidden rather than display:none. I have omitted some general styling, you can have a look at the link for the github repository.

.submenu {
  position: absolute;
  padding: 0;
  list-style: none;
  height: 0.5em;
  width: 0.5em;
  overflow: hidden;
  clip: rect(0.5em 0.5em 0.5em 0.5em); //visually-hidden
  clip: rect(0.5em, 0.5em, 0.5em, 0.5em);
}
.menu_item:hover .submenu {
  padding: 0.5em 0;
  width: 9em;
  height: auto;
  background: #111;
  clip: auto;
}

The navigation bar looks something like this now. However, the next thing to notice here, you cannot visually focus on the submenu options using the Tab key and hence the accessibility has been broken now.

styled navigation with hover

To solve this issue, we have :focus-within to the rescue. It is a pseudo-class that represents an element that has received focus or contains an element that has received focus. This allows us to open the submenu when a submenu element is focused.

.menu_item:focus-within .submenu {
  padding: 0.5em 0;
  width: 9em;
  height: auto;
  background: #111;
  clip: auto;
}

It works pretty well for the menus to be able to navigation forward and backward using Tab key and Shift+Tab respectively.

styled navigation with keyboard accessibility using TAB
NOTE :The pseudo-class :focus-within is not really supported for IE and some older browsers. Go check out the compatibility in the{" "} link for browser support {" "} . You might want to consider using a polyfill for the same. I used an alternative method of using "focus" class. Link for the code is here. The repository has both of the mentioned approaches for reference.

To further make it even more functional, let us write some javascript to be able to switch menus using the left and right arrow keys. To get started, add an EventListener for the same.

document.addEventListener("keydown", function(e) {
  l = document.activeElement.parentElement;
  // handling for change of menu when right arrow key is clicked
  if (e.keyCode === 39) {
  }

  // handling for change of menu when right arrow key is clicked
  if (e.keyCode === 37) {
  }
});

Here, activeElement gives us the currently focused element which in this case will always be the anchor tags hence we refer to the parent element (<li>) of the same.

To move to the next menu i.e. when the right arrow key is clicked we simply focus on the firstElementChild of the next sibling menu. The catch here is that since anchor tags are focusable and not <li>, we need to retrieve <a> using the firstElementChild. Another case to be taken care of is the fact that if the submenu item is currently focused, we need to retrieve the parent menu to be able to move to the next menu(say, immediate right menu). To understand it better, have a look at the code below.

// handling for change of menu when right arrow key is clicked
if (e.keyCode === 39) {
  if (l.classList.contains("submenu_item")) {
    //retrive the parent menu_item
    l = l.parentElement.parentElement;
  }
  if (l.nextElementSibling !== null) {
    //focus on the <a> of the previous menu_item
    r = l.nextElementSibling;
    r.firstElementChild.focus();
  }
}

Now that we've managed to move to the next menu_item, moving left should not be that hard.

if (e.keyCode === 37) {
  if (l.classList.contains("submenu_item")) {
    //retrive the parent menu_item
    l = l.parentElement.parentElement;
  }
  if (l.previousElementSibling !== null) {
    r = l.previousElementSibling;
    //focus on the <a> of the previous menu_item
    r.firstElementChild.focus();
  }
}

Congratulations !!! You've your accessible navigation menu ready.

styled navigation with full keyboard accessibility

That is how a few lines of code can make your product reach out to a larger audience. Businesses need to take care of their customers to provide them with better services and a sense of inclusion for all. Hence, always practice A11Y.