Don’t Use ARIA Menu Roles for Site Nav
Once again, the advice is in the title of the post. But I will ramble anyway since you scrolled this far. First run with the advice, and then review some background on ARIA and how navigation and menu items are defined. This way you can tap out quickly when it gets even more boring.
Why You Avoid
A properly-coded web page navigation menu needs no ARIA. Once you add ARIA, however, you have put yourself on the hook to handle some complex interactions.
First, you need to understand that assistive technology (screen readers) that supports ARIA menu roles will announce the menus as such, which is a cue to the user that the interaction changes. Now instead of just using Tab↹ and Shift + Tab↹, you are effectively telling the savvy user that your menu also supports Enter, Space, ↓, ↑, →, ←, Home, End, Esc, and Shift + F10. I listed all those keys for a reason, which I explain in the ARIA section.
Second, you need to consider that these keyboard commands are not exposed to users in any way (unless you educate them), so a user who might want to use one of these keys for its traditional purpose on the web page will instead trigger the function in your menus. Imagine how confusing it might be to hit Space to scroll the page and have a new nested menu open instead.
Third, you have to make sure that your ARIA roles are correctly nested and on the right elements. Missing a role or dropping one onto the wrong control can wreak havoc and make your site navigation completely unusable to the very users you are trying to support.
Fourth, many menu constructs use a lot of additional HTML that is not needed, some of which come with their own semantics that you want to override. For example, you may have elements that do not hold navigation items but instead hold design items. This element may confuse the menu user when it is announced, while dropping a
aria-hidden can render an entire menu invisible if not applied in the right location.
The rest of the post is just information to back up my assertions. You could stop reading here and be fine, but if you want to understand my argument or just need to fall asleep, read on.
Oh, if you got to this post because you want to implement a more complex navigation menu than a few links, that’s not what I am doing here. However, there is a great post over at Inclusive Components that covers Menus & Menu Buttons and should get you going in the right direction.
Now for the music…
ARIA, or Accessible Rich Internet Applications, is essentially a bridging technology between HTML and assistive technology. It allows developers to approximate native applications using HTML, among other benefits.
For the scope of this post I am leaning on the native application replication aspect of ARIA. Specifically, re-creating menus as they appear in installed desktop applications.
I’d also like to point out that ARIA has some “rules” for its use (those are not scare quotes, but it acknowledges that the rules are really strong recommendations). The second rule tends to apply where I am going:
Do not change native semantics, unless you really have to.
ARIA has a few roles that define and describe menus. The definitions that follow come from ARIA 1.1.
menuis often a list of common actions or functions that the user can invoke. The
menurole is appropriate when a list of menu items is presented in a manner similar to a menu on a desktop application.
menubarrole is used to create a menu bar similar to those found in Windows, Mac, and Gnome desktop applications. A menu bar is used to create a consistent set of frequently used commands. Authors should ensure that
menubarinteraction is similar to the typical menu bar interaction in a desktop graphical user interface.
- An option in a set of choices contained by a
There is no element in HTML5 that behaves like a menu bar in a native application. It makes sense to apply these roles when you are replicating a desktop application.
ARIA has a single role to define and describe web site navigation. The following definition comes from ARIA 1.1.
- A collection of navigational elements (usually links) for navigating the document or related documents.
Conveniently, HTML5 has an element that does this job on its own —
<nav>. Modern browsers and assistive technology recognize the element’s semantics and convey it accordingly, so there is no need to use the ARIA role any longer (for an audience that you believe is on reasonably current technology).
ARIA Menu Pattern
Putting all the ARIA roles into practice and understanding which to use can be tricky. The WAI-ARIA Authoring Practices 1.1 document is intended to be a guide for developers, providing copy-paste-ready code for common user interface patterns.
This document even defines a pattern for menus, providing guidance and sample code. This sample code includes the nesting requirements and the ever-complex necessary keyboard navigation support covering the following: Enter, Space, ↓, ↑, →, ←, Home, End, Esc, Tab↹, Shift + Tab↹, and Shift + F10.
The issue with this pattern is that the document does not make it clear that this pattern should only be used when trying to replicate an application menu.
To clarify — if you are rebuilding the interface for Microsoft Word, then the File menu gets
role="menu", lives inside a
role="menubar" container, all while File → New, File → Open, File → Save, and so on each get
I have filed an issue against the ARIA Practices document to clarify all of this, on which you are welcome to comment or vote.
Web Site Navigation
A typical web site is not an application. Sure, some claim to be “web apps”, and even make sweeping statements about how that is different than being a web page, but for the most part, web sites, single-page applications (SPAs), blogs, news sites, and so on are not replicated installed native applications.
As it stands today, using standard valid HTML for site navigation is a perfectly accessible method of navigating a site. The simplest pattern involves using the
<nav> element, which acts as a landmark for screen readers and announces its purpose, nested
<li>s for the navigation items, which provide a count and position within the list, and a proper
<a href="…"> for each link, which provides an accessible name and a keyboard stop.
The pattern itself is as simple as this:
Really, This Is a Thing
Somehow many developers have come to the conclusion that a web page is inaccessible unless it uses ARIA. This is a combination of patterns that do not use semantic HTML, a misunderstanding of ARIA, and not having practical experience with assistive technology.
A stroll through Stack Overflow shows the use of menu roles is way too common, and when I encounter them I try to guide users away from using them at all.
For a time, the Adobe Accessible Mega Menu made use of roles that did not fit, and while it was fixed a while ago, there are many implementations that have not been updated. Further, people may be copying that code from older sites or projects, continuing to perpetuate the problem.
Tutorials often get it wrong, such as the always useless W3 Schools in its Bootstrap documentation. Not that Bootstrap is off the hook, given that its 2.x documentation recommended menu roles and I still see that code copy-pasted into projects today.
The point is, mis-use of ARIA menu roles is common. Common enough that I encounter them in accessibility audits, added by developers who have no idea what they do nor why they are there. Let’s break that cycle.
Update: September 27, 2018
Nearly a year since I wrote this, and bad information in the APG spec still persists.
Most recently a developer at Twitter was asking for help on how to set up a control using the APG menu role description. I argued that his example was not a menu, and he offered the text from the APG spec:
But according to the desc of a menu it seems much more like that than a disclosure:
"A menu is a widget that offers a list of choices to the user, such as a set of actions. A menu is usually opened, or made visible, by activating a menu button"
I filed an issue against the ARIA Practices document in April 2017 to address this language specifically. That issue was not accepted and instead turned into a Gish Gallop from the active editor of the guide. As a result, we have a developer from one of the larger platforms on the web about to encode demonstrably confusing and anti-user behavior. And it is not his fault. He is trying to do it correctly
Marco Zehe not only weighed in on the mis-use of the menu role in the thread (as did Léonie Watson), but he wrote a blog post with essentially the same message — do not use ARIA menu roles: WAI-ARIA menus, and why you should generally avoid using them
The solution is plain and simple: Generally, don’t use
menuitemradio. Only if you build something like Google Docs and deal with what you get when you press Alt+F (or Alt+Shift+F in Firefox), these are warranted. In most likely all other cases, they are not.
If you want to build a Windows95-style menu bar with only menu items, checkboxes or radios, that will not be used on mobile, and that you can guarantee will support all the necessary keyboard interactions outlined in the APG, then go nuts. Otherwise, do not.
On top of that, please understand that the WAI-ARIA Authoring Practices is a note, not a specification. It is not a standard. It is the output of an opinionated set of editors (which in itself is not bad)
Update: June 26, 2019
I finally got around to coding my disclosure-widget navigation. It sounds impressive when I use that term, but essentially it is a list of links, and some of those links have more links associated with them (sub-pages) that are hidden until the user chooses to see them. Simple concept, simple code, less awful for keyboard and screen reader users. Decide for yourself: Link + Disclosure Widget Navigation
Totally agree that:
- the menu and menuitem roles are used incorrectly more than they are used correctly.
- We need to put a stop to incorrect use!
- For a simple list of links, and for most site nav, they are not the ideal pattern.
The point of the ARIA practices is to promote correct use and thus help eliminate incorrect and damaging use.
However, none of that means that there are never situations where site nav isn’t massively more accessible to a broad set of users, both sighted and blind, both mouse and non-mouse, by implementing either the menu or menubar pattern.
There is a lot more to say on this topic. But, it is important to keep in mind that:
- There is no single design for nav that is best everywhere.
- A primary objective of ARIA is making accessible web-based GUIs possible.
- GUI elements do not have to be limited to traditional desktop purposes.
Matt, when you sayThe point of the ARIA practices, I am assuming you are referencing WAI-ARIA Authoring Practices 1.1. I think it’s a great document and I reference it all the time in training, documentation, etc.
As a result of referencing it so frequently, I also have heard back regularly that the menu pattern in particular is confusing and, for those who read the ARIA spec itself for menus, confuses the issue. It is what led to me filing an issue in April to adjust the language describing the pattern, yet not suggest change to the code.
As for your points:
- Completely agree
- I also agree, except the plain HTML pattern I outline above is already accessible and does not need ARIA. In fact, adding it has, in my experience, made menus less accessible.
- I agree GUI elements do not have to be limited to desktop mimicry, and I think ARIA live regions are a great example of this. I think the ARIA menu pattern, however, should be limited unless there is a hell of a lot of testing saying otherwise.
I generally avoid absolutes in my blog posts (and titles), but in this case I feel my advice is appropriate. Plenty of practical (and anecdotal) experience supports this. There are always exceptions, but I’d rather someone has to make a damn good case for it.
This is a very timely post, as I’m currently working on a project where I evaluated that the menu design pattern was appropriate. But now I might need to reconsider it.
I was, indeed, misled by the WAI-ARIA Authoring Practices document, that implicitly validates the use of this pattern for navigation menus, through its examples. My starting point was a burger menu, and when trying to find guidance on broadly agreed keyboard behavior, I felt the menubutton pattern was a solid ground for this, especially because the document provides an example of a menu button for a navigation menu… And while I was at it, I went through the whole pattern and duly documented how to properly implement all the roles and attributes for that — even the roving tabindex algorithm. And the devs actually, and properly, implemented it. Doh.
The story does not end here. This burger menu is, in this responsive design website, just the narrow-screen version of a more classical menu (fixed list of links). Of course I didn’t intend that the menubutton/menu design pattern also applies to the wider-screen version, but since the ARIA stuff is embedded as static HTML, it’s still there, no matter how wide is the viewport.
I feel rather angry about this document now, because it really is deceptive on this matter (also, note that the so-said nav menu example is actually faulty in many ways: its code is utterly flawed, keyboard navigation doesn’t work with VO on Mac… the list of issues is telling). And slightly angry at myself for not reading the whole list of open issues for the document — but hey, who would go through this, frankly?
I used to think that the published W3C documents were reliable enough. I understand this is a working draft, but since it’s online, shouldn’t it be more carefully reviewed? And when additional resources, such as these examples, are evidently flawed, shouldn’t they be discarded until they are fixed?
Ok, now time for a difficult message to the devs who struggled with this pattern…
Thanks for this post, though, you probably avoided me more trouble in the future!
Olivier, on one hand, I am impressed that you made a menu pattern that conforms to all the requirements outlined in the draft ARIA practices document. At the very least, save that pattern in your library!
On the other hand, I feel your pain. I wrote this post because I have seen that very thing happen too often, and heard the frustration from clients in user testing when users have no idea how any of this works nor why their regular method of navigating sites is broken on this one.
Draft documents can be dangerous for those not steeped in the standards process. It’s how we got people advocating for all-
<h1>pages because they believed the Document Outline Algorithm was a real thing before it even made it into a final spec (which it did not).
Hi Adrian, I am glad that you raised this point. I have been following this guidance because it was in the ARIA Authoring Practices document. I see value in having the site navigation be a single tab stop on the web page with arrow keys for navigation inside it for increased efficiency. Unfortunately, the trade-off for that is that users have to become trained to understand that new interaction model. I am glad you have logged your thoughts with the document as ultimately I will implement and train others based on what becomes the established practice.
Thomas, unfortunately the current Authoring Practices document is a draft. The 1.0 version is… hard to find.
I understand the potential value of having the menu as a compound widget (one tab-stop on the page), though I am always wary of any assertions about ease of use or efficiency barring usability testing with the target audience. Especially since this pattern is not extant on the web, and primarily only in installed applications.
All that being said, I look forward to clarity from the document and consistency across the web. Please feel free to weigh in on the open issue as well, since the loudest / grumpiest voices should not be the only ones represented.
Hey, great read, just a quick one, you’ve misspelt Bootstrap in the second last paragraph under the title “Really, This Is a Thing”
“Tutorials often get it wrong, such as the always useless W3 Schools in its Bootsrap documentation. Not that Bootstrap is off the hook”
so what you’re really saying is that you’re just a lazy prick and that adding ARIA is just too much hassle … well, using a screen reder every day, I’d appreciate a menu role here and there rather than some moron relying on a pattern from the ninetiess like a (&*(*&ing mega menu … trying working through one of those pieces of ‘accessible’ crap on your favourite website?
Clearly I am a lazy prick, and it is easier to write a post about demonstrated ARIA mismatches with extant patterns (coupled with developer failure to handle keyboard support that the role dictates) than it is for me to add ARIA to my menus.
You got me.
I agree with you that ARIA menus are confusing & need a bit of learning, as a screen reader user I prefer ARIA menus now rather than plane HTMML items while navigating in a mega menu. It is easy to navigate using arrow keys instead of tabbing through all the HTML links inside a mega menu. Just my Perspective.
Raghavendra, I agree that being able to use arrows in mega-menus is generally easier. My issue is not with that (arrow key navigation nor the utility of mega-menus). My issue is that APG asserts that all navigation menus should be treated as native application menus regardless of how simple they are.
A million thanks for this post. It’s one of the most useful links I can share with others.
As someone (re) discovering a career path involving web dev, I can’t thank you enough for this post. It reinforces the scepticism i experienced while attempting to reconcile the aforementioned misleading design examples with the aria spec itself. Intuitively i felt the recommendations to be problematic, but wondered if it was my understanding that was in error since people much more experienced than i were following the nav menu pattern religiously. It’s good to hear a dissenting voice, one confirming my suspicions, from someone with the cred to lend authority to their views.
I’m currently in the process of developing an html framework to base future personal projects on – very much a learn-by-doing approach to building my web development skill-set – and this post has definitely saved me from either a lot of unnecessary work, a poor final product for consumers with accessibility concerns, or (likely) both.
When flagging the use of
role="menu"in a manual accessibility audit, what success criteria do you think it best falls under? SC 2.1.1 Keyboard? 4.1.2 Name, Role, Value? It seems like it could fall under a few SC. Thanks!
I would not fail it, but as you say I would flag it. 4.1.2 strikes me as the best fit because it is assigning a role (and required sub-roles, etc) that does not fit the purpose.
Thank you for a great rundown, Adrian!
Out of curiosity; how do you find using
aria-haspopup="true"as this is supposedly interpreted as the popup being of the
role="menu"? Is this a good use-case for a “menu”?
Tobias, you are correct that
aria-haspopupgenerally corresponds to a menu. According to the spec,authors MUST ensure that the role of the element that serves as the container for the popup content isIn short, if you have recreated a native menu then you need
dialog, and that the value of
aria-haspopupmatches the role of the popup container.