What is best practice to enhance the semantic accessibility of a website <nav>
landmark with a nested <ul>
list for screen reader users? (aria-label and list level are currently not pronounced by all screen readers)
I tested with Voiceover on iOS 9, Talkback on Android 5 and NVDA 2016-1 on Win10 (in Firefox). I used (mostly) default settings in the screen reader applications.
I thought the following list should be optimal prepared for screen reader users:
Demo code 1
<nav>
<ul aria-label="product navigation">
<li><a href="product-a.html">Product A</a>
<ul aria-label="sub menu Product A">
<li><a href="product-a-spec.html">Specifications</a></li>
<li><a href="product-a-acce.html">Accessories</a></li>
</ul>
</li>
<li><a href="product-b.html">Product B</a>
<ul aria-label="sub menu Product B">
<li><a href="product-b-spec.html">Specifications</a></li>
<li><a href="product-b-acce.html">Accessories</a></li>
</ul>
</li>
</ul>
</nav>
Expected result: Screen reader say something like this:
- Beginning of navigation landmark
- Beginning list level 1 "product navigation" with two elements
- "Product A" link
- Beginning list level 2 "sub menu Product A" with two elements
- "Specifications" link
- "Accessories" link
- End of list level 2 "sub menu Product A"
- "Product B" link
- Beginning list level 2 "sub menu Product B" with two elements
- "Specifications" link
- "Accessories" link
- End of list level 2 "sub menu Product B"
- End of list level 1 "product navigation"
- End navigation landmark
I also expected detailed info when touching sub menu items on table/phone, e.g.
- "Specifications" link level 2 list "sub menu Product B"
But unfortunately this is not working in Voiceover, Talkback or NVDA.
The list labels and the list level are both not spoken.
When using a screen reader and jumping from list to list (like using l
key or the list rotator/navigation) you have no idea, what list you're in. In case the elements of the children lists have similar links (like in the demo code) this problem seems for me to be even worse.
I also think it is very confusing (at least for me) to hear "beginning of list" and "end of list" multiple times with no hint, what kind of list is beginning or ending - especially when you are on a mobile or tablet and discovering the display content randomly with your finger.
I made a test series and tried different variations, e.g. I added explicit role="list"
and "listitem"
. I also added aria-level="1"
and "2"
to the listitems as shown in this example - without success. Are list levels supported by any screen reader software?
One of my findings: At least Voiceover (on iOS) is telling the aria-label of the <ul>
elements, but only when defining explicit role="list"
like in the following code. But this also only works when the <nav>
container is not used - Voiceover (on iOS) is ignoring the fact that there is a list completely when using <ul>
within <nav>
. So when using a <nav>
landmark the list is gone in Voiceover and also not accessible via the rotator/list navigator.
Demo code 2
<ul role="list" aria-label="product navigation">
<li role="listitem"><a href="product-a.html">Product A</a>
<ul role="list" aria-label="sub menu Product A">
<li role="listitem"><a href="product-a-spec.html">Specifications</a></li>
<li role="listitem"><a href="product-a-acce.html">Accessories</a></li>
</ul>
</li>
<li role="listitem"><a href="product-b.html">Product B</a>
<ul role="list" aria-label="sub menu Product B">
<li role="listitem"><a href="product-b-spec.html">Specifications</a></li>
<li role="listitem"><a href="product-b-acce.html">Accessories</a></li>
</ul>
</li>
</ul>
I think when using a nested list it is important to tell the blind user the nesting level and the list label (at least for the sub level lists, so you know that it is a sub level list) - is there currently a way to solve this?
In case it is not possible, I'd say that it is not a good advice to use nested lists in <nav>
for navigation... or nested lists at all?
Edit 1: Updated demo code
Edit 2: More findings
In this answer to another question is made clear, that there are no fixed rules about how screen reader should handle/read aria-label.
<nav>
and <ul>
are grouping elements - according to the answer the labels are more likely to be read - unfortunately not in my tests when there are nested lists in a navigation landmark.
I also found a page listing some screen reader test results for unordered nested lists - at the beginning they state what "should be announced", so it's optional. :/ The Voiceover results of this page are not valid for Voiceover on iOS 9, the nesting level is not announced in my test.
On the NVDA GitHub issue tracker there are also multiple discussions about the way to implement support for aria-label. And I also found this long but really interessting article about the ridiculous complicated world of aria-label.
Anyway, so now I know I can't expect that nesting levels or aria-labels are announced by default. I'm still wondering if there is a way to enhance accessibility for blind users when the screen reader software doesn't support this functionality...