Creating accessible menus-Part 1

I’ve recently been tweaking my site navigation to make it a bit cleaner and more accessible. Even though my menu is super simple I wanted to share the process with you in the hopes that it might be useful to anyone looking to make their own navigation more accessible.

Basic structure

As I mentioned the navigation for my site is extremely simple, it’s basically just five links to the various areas of my blog. So I started out with a clean, semantic list of links wrapped in a nav element. Since I use Jekyll to build my blog there’s a little bit of liquid markup in the links themselves, but not much else.

<nav>
<ul>
  <li><a href="{{site.baseurl}}/index.html" title="articles">Blog</a></li>
  <li><a href="{{site.baseurl}}/about.html" title="learn more about me">About</a></li>
  <li><a href="{{site.baseurl}}/speaking.html" title="speaking engagements">Speaking</a></li>
  <li><a href="{{site.baseurl}}/contact.html" title="contact me">Contact</a></li>
  <li><a href="{{site.baseurl}}/tags" title="all posts">Archives</a></li>
  </ul>
</nav>

As the HTML5 structural elements are well supported by assistive technologies I don’t need to add an ARIA landmark role to the nav element, it’s accessible just the way it is. I can’t stress enough how the majority of your accessible needs can be met by just ensuring that you have clean, standards-based markup. Too often developers find themselves having to bolt on accessibility to code simply because it wasn’t written properly to begin with.

Adding an accessible name

It’s a good idea to ensure that any element or region that can be interacted with has an accessible name. These can be used by assistive technology to identify the element or give more information about it. Many HTML elements already have mechanisms that are used to generate accessible names such as the alt attribute on img elements or the text within a link. If you are new to the concept of accessible names The Paciello Group has a nice introductory article on them.

In the case of my site navigation each of the links has their own accessible name based on the text within the links. However the nav element representing the site’s main navigation does not. It’s always bothered me that both the HTML5 outline algorithm and the WAI-ARIA landmark roles have no way to identify different types of navigation blocks, specifically a site’s main navigation. Although my site is very simple I might choose later on to add additional blocks of navigation or groups of links. If I decide to use a nav element for each of them how are assistive user agents supposed to tell them apart? David Storey recently proposed adding a type attribute to the nav element as a way of identifying and correctly mapping their roles. Until something like that is adopted we still need to be able to identify the site’s main navigation.

I could have added a heading to my nav element, but to me that seems overly intrusive and a bit of an overkill for what I need. Thankfully there’s an easy way to add accessible names to elements that don’t have built-in mechanisms for them by using ARIA. The aria-label and aria-labelledby attributes allow us to provide alternative accessible names for elements. By adding the aria-label attribute to my nav element I can correctly identify it as my site’s main navigation. I modified my nav element to look like this:

<nav aria-label="main navigation">

Skipping navigation

Although my site nav is pretty small I doubt that anyone using a screen reader is going to want to hear the menu read every time they browse to a page. Even though I have the main content identified by using a <main> element giving users a way to skip past the navigation directly to the content is a good idea. Skip nav links have been around for a long time, and I didn’t see the need to reinvent the wheel here. I pretty much used the same approach that WebAIM uses on their site. Just below the opening body tag I added:

<a class="skipnav" href="#main">skip to main content</a>

I made sure to add the corresponding ID attribute to my main element and then switched my attention to styling my skip navigation link. Obviously I didn’t want the skip navigation link to be visible by default but I did want it to become visible if focus was established on it. That way keyboard users could take advantage of it as well. I had to tweak the positioning a bit to ensure that it appeared where I wanted it to but overall the styling is pretty simple:

.skipnav {
	padding:.5em 1em;
	position: absolute;
	top:-40px;
	left:0px;
	color: white;
	border-radius:0 0 8px 8px;
	background: transparent;
	-webkit-transition: top 1s ease-out, background 1s linear;
    transition: top 1s ease-out, background 1s linear;
}

.skipnav:focus {
	position:absolute;
	left:0px;
	top:0px;
	background:#991B1F;
	outline:0;	
	-webkit-transition: top .1s ease-in, background .5s linear;
    transition: top .1s ease-in, background .5s linear;
}

To hide it I simply positioned it above the top of the page, that way it’s not hidden from screen readers or other assistive tech. I added a position: relative to the body element at large screen sizes to ensure that it appears just above the title of the site and added a simple animation so that its appearance wouldn’t be too jarring for keyboard users.

Next steps

With the basics out of the way I needed to tackle two remaining things. First, I wanted to identify which link indicates the current page and then I needed to make the menu responsive and find a way to create an accessible toggle for the menu at small screen sizes. I’ll cover how I approached those challenges in my next post.

Read more: