Bulding a navigation element without using lists: an accessibility test

Since the beginning of the web that navigation links are usually put inside an unordered list (<ul>) in which each item is identified in the list as an <li>.

<ul> 
<li><a href="#">Link 1</a></li>
<li><a href="#">Link 2</a></li>
<li>...</li>
</ul>

In terms of accessibility, this is good because screen readers will always read “list with X items” and then they’ll read each item on the list individually. In the end, some screen readers also say “end of the list”.

HTML5

With the arrival of HTML5, some new, more semantical tags appeared, that could give more meaning to the elements on the page. Amongst those new tags, there’s the <nav> tag.

As HTML5 was gaining popularity and support from the major browsers, web designers started using these new tags, and so, the navigation went from a simple list to a list inside a navigation block:

<nav> 
<ul>
<li><a href="#">Link 1</a></li>
<li><a href="#">Link 2</a></li>
<li>...</li>
</ul>
</nav>

In order to improve accessibility, it was recommended that an ARIA Role should be added to the navigation block so that the browsers that don’t fully support the new tags could recognize it’s semantic meaning. And so, the <nav> started to have the redundant “role” attached:

<nav role="navigation"> 
<ul>
<li><a href="#">Link 1</a></li>
<li><a href="#">Link 2</a></li>
<li>...</li>
</ul>
</nav>

However, in all browsers tested, with or without “role”, the navigation element is successfuly identified by the screen readers. Only in older browsers (like IE8) it is ignored, but if we are going to use HTML5 tags and still need to support older browsers, we can use HTML5Shiv, a script that helps older browsers interpret the new HTML tags,

With this script, even IE8 interpreted correctly the navigation block using a screen reader, wich indicates that we really don’t need the redundant “role” when the <nav> element itself already has this semantic meaning out of the box.

This is how, in the last few years, most navigation blocks have been written by web designers, in the name of accessibility and the semantic of the new tags. But is it really better than using a simple list?

How screen readers interpret the two types of navigation?

If we test a navigation made with a simple unordered list (ul) against a navigation inside a navigation block (nav > ul), we can see that the latter is much more verbose to the users, and as so, potentially more confusing.

In a test with the 3 most popular screen readers (JAWS, VoiceOver, NVDA), the results were as follows:

ul > li > a
All screen readers read “List of X items”

nav > ul > li > a
JAWS: Reads “Navigation region“ and then “List of X items”
VoiceOver: Ignores the navigation block and just reads “List of X items”
NVDA: Reads “Mark: navigation” and then “List of X items”

As we can see, all screen readers, except Apple’s VoiceOver, read both the navigation block and the list, resulting in more audio “noise” to the user navigating the page.

VoiceOver ignores the navigation block completely, and just reads it as a normal list.

What if we don’t use lists?

What happens if we just put a bunch of links inside a navigation block <nav>?

This is valid HTML5 code and, theoretically, it will reduce the amount of information the screen readers read, at the same time giving it a semantic meaning (something we can’t do with a simple <ul>, because we can’t just add a role=”navigation” to this element).

<nav> 
<a href="#">Link 1</a>
<a href="#">Link 2</a>
<a href="#">...</a>
</nav>

Looking at this markup, you may think this makes no sense, but if we read the HTML specs for the <nav> element, this is a valid solution.

A nav element doesn’t have to contain a list, it can contain other kinds of content as well. In this navigation block, links are provided in prose.

Additionally, we can have other elements (that are ARIA landmarks) that can have a navigation without it being inside a list.

Not all groups of links on a page need to be in a nav element — the element is primarily intended for sections that consist of major navigation blocks. In particular, it is common for footers to have a short list of links to various pages of a site, such as the terms of service, the home page, and a copyright page. The footer element alone is sufficient for such cases; while a nav element can be used in such cases, it is usually unnecessary.

For instance, having a navigation inside the <footer> tag, like this, is also valid.

<footer> 
<a href="#">Link 1</a>
<a href="#">Link 2</a>
<a href="#">...</a>
</footer>

In terms of markup, this solution is much simpler, because we have a direct relation nav > a instead of nav > ul > li > a.

Testing it in the screen readers, we get the following verbalizations for this element:

nav > a
JAWS: “Navigation region”
VoiceOver: “Navigation with X items”
NVDA: “Mark: navigation”

All screen readers detect correctly the navigation block, and VoiceOver goes even further, as it indicates also the number of items, just like a list.

Testing with real users

Based on these results, I made a test with some blind users (regular screen reader users) to know their opinion on which navigation as more intuitive.

The first feedback I got, was that there were no significative differences between the two versions. However the nav > ul > li > a, for being longer (most screen readers read both the navigation block and the list) was the less preferred.

Based on the test results and the feedback from real users, we can safely say that having a group of links directly inside a navigation block <nav> is an effective solution that maintains the semantic of the element and isn’t too verbose for the user.

The version that we see every day (putting an <ul> inside a <nav>) tends out to be the worst because it creates an unnecessary redundancy in the code and in the words that the screen reader says.

What about sub-menus?

With lists, creating a sub-menu is trivial. We just start a new list inside the element that we want to have sub-items. We can create infinite levels, however, for the sake of usability, keep it under 3 levels of hierarchical navigation.

<nav> 
<ul>
<li><a href="#">Link 1</a></li>
<li><a href="#">Link 2</a>
<ul>
<li><a href="#">Sub-link 1</a></li>
<li><a href="#">Sub-link 2</a></li>
<li>...</li>
</ul>
</li>
<li>...</li>
</ul>
</nav>

Unfortunately, the <nav> element doesn’t contemplate (in a semantical way) the nesting of sub-navigations. Any combination of nav > nav results in a mess for the screen readers. They don’t understand that it is, in fact, a navigation inside another navigation and treat them as if they were two independent navigations, one in the middle of the other.

One possible solution would be to use the aria-owns attribute to give a hierarchical meaning to the navigation block. Acording to the specs, we can create a relation “parent/child” between two elements in the DOM using this attribute, like this:

<nav role="navigation"> 
<a href="#">Link 1</a>
<a href="#" aria-owns="SubLink2">Link 2</a>
<nav id="SubLink2">
<a href="#">Sub-link 1</a>
<a href="#">Sub-link 2</a>
</nav>
<a href="#" aria-owns="SubLink3">Link 3</a>
<nav id="SubLink3">
<a href="#">Sub-link 1</a>
<a href="#">Sub-link 2</a>
</nav>
<a href="#">Link 4</a>
</nav>

However, when testing this approach with the screen readers, it still isn’t clear that they understand this hierarchy. Basically, the screen readers just identify a navigation region in a middle of another navigation region, in a way that the user doesn’t understand there is a “parent/child” relationship.

Additionally, since the “parent” element is an <a>, before reading the child element <div> the screen reader reads “link navigation region”, which means that it concatenates the both elements (link and navigation region) and reads them together, resulting in more confusion for the user.

In order to try and solve this issue, I tried putting the links inside a different element, like a <span>:

<nav role="navigation"> 
<span><a href="#">Home</a></span>
<span aria-owns="SubLink2"><a href="#">Sports</a></span>
<nav id="SubLink2" role="navigation">
<span><a href="#">Football</a></span>
<span><a href="#">Basketball</a></span>
</nav>
<span aria-owns="SubLink3"><a href="#">Economy</a></span>
<nav id="SubLink3" role="navigation">
<span><a href="#">Finances</a></span>
<span><a href="#">Money</a></span>
</nav>
<span><a href="#">Tecnology</a></span>
</nav>

This solved the previous problem of the screen reader concatenating the two elements, however, it’s still hard to navigate because not all screen readers communicate the end of a navigation region (like they do with lists). This way users don’t know when a sub-navigation has ended before the screen reader continues on to read the items of the next navigation block.

Conclusion

Based on these data, for a simple navigation (only one hierarchical level) it’s better to use a simpler markup like nav > a, or even footer > a.

For more complex navigation structures, with several hierarchical levels, in terms of accessibility, it’s better to keep using lists. They allow the browser to understand the hierarchy, creating a logical tree-like view of the contents.