WAI-ARIA menus, and why you should generally avoid using them

The WAI-ARIA standard defines a number of related menu roles. However, in 99% of all cases, these should not be used.

A bit of history

In the mid 2000s, people were arguing over whether HTML4.01 or XHTML 1.x was the better standard. Both markup languages had in common that they hardly knew anything about advanced widgets. However, such widgets were more and more asked for, by web developers around the world, but because standards processes were very slow, and browser vendors were not that many as today, things were moving too slowly.

So, web developers started wildly implementing these with div and span elements and style them to look like desktop counterparts. This was to create richer user experiences for their web sites which were slowly transitioning to become web applications.

Back then, people were still using mostly desktop applications that had classic menu bars with dropdown menus, on operating systems like Windows XP. The Mac still knows these today, Windows, however, has moved away from them in modern applications.

WAI-ARIA to the rescue

To somehow cope with the influx of new web experiences, the WAI-ARIA standard was brought to life by a group of very talented people, to map desktop concepts to the web, and give web authors the means to communicate to desktop screen readers what desktop equivalent of a widget was being created. Screen readers were thus given the information to deal with these widgets in a similar way as they would in desktop applications.

One set of widgets were menu bars, menus, menu items, and their siblings menuitemradio and menuitemcheckbox. These were to mimic a menu bar, menus that popped up from these, and the three types of menu items that Windows, Linux/GNOME and Mac knew about. Screen readers reacted to these menus the same way as for desktop applications. Because of a long history of no proper programming interface support, especially on Windows, screen readers had to hack together special so-called menu modes for applications, because technically, focus was in two places at the same time, or so it seemed. And there were a bunch of other problems and quirks.

The important takeaway is that menuitem and friends provoke a very specific set of expectations within users and screen readers of a web application’s behavior. A menu can only contain menu items, for example, a menu bar only menus, and such. Also, the keyboard is expected to behave in a very specific way: A set of menu bar items is traversed from left to right (or right to left in RTL languages), menus are dropped down with Enter or DownArrow, the menu is closed with Escape etc.

The problem

Over the years, it has become very apparent that these concepts are, with the receeding of menus especially on Windows, less and less known to people. Many web developers lack the context of this complex set of widgets and the expected interaction. One of the most common ARIA errors we see in the wild comes from improper uses of the menu roles. Often, menu items are used without proper menu parents, resulting in totally improper behavior by assistive technologies. A screen reader could get stuck in their menu mode, for example, because the web author doesn’t signal when a menu has been closed.

Generally, it seems that web developers read about these menu roles, and think a set of links within a list that may pop open another sub set of links is enough to warrant it calling a menu. Well, let me put it bluntly: Nope. Because these then don’t support the expected behavior, links bring you to other pages instead of performing an action, and thus are a totally different type of widget, etc.

Likewise, a button that, when pressed, pops open a set of options or actions to choose from is often coded as a menu. While this seems correct at first glance, it, too, means that you have to use at least menu and menuitem, and the proper set of key strokes. But in general, because of all these problems that screen readers have to deal with when it comes to menus in desktop applications, even such an experience is often not as good for users. While NVDA and Firefox might cope fine in an instance, JAWS may react differently, and where both JAWS and NVDA might cope well, VoiceOver might fall over, or any other combination of these. Trust me, I have seen them all over the years.

The solution

The solution is plain and simple: Generally, don’t use menu, menuitem, menubar, menuitemcheckbox, or 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.

Even when you have a button with aria-haspopup=”true” and aria-expanded=”true” or “false”, depending on whether the popup is shown or not, the user experience is usually better if the container of your popup items is an ul element, and the buttons or links that perform actions are just part of a list, normal li elements within that ul. You can still implement keyboard navigation like moving from button to button with arrow keys, and you must make Escape close that popup and return focus to the button that opened the popup, but leaving all the menu related roles out of the game makes the user experience that much better. Remember that WAI-ARIA roles hide the normal semantics. A user actually needs to know if the item is a button, which performs an action, or a link, which is most likely going to take them to another page within your site.

One that doesn’t know about menus

And here’s another aspect that I intentionally left until last: Mobile doesn’t know about these old desktop concepts of menu bars and pull-down menus at all. So the user experience for such roles is even more unpredictable than on desktop. Buttons and links, on the other hand, are very well supported on mobile as well. Other pop-ups on mobile operating systems contain these normally, too, so this is a totally expected and consistent user experience.

Conclusion

In my opinion, these menu* roles should be deprecated in WAI-ARIA 2.0, but I realise that that might not be feasible. Moreover, since we do have applications like Google Docs which implement such a menu system, we still need them. But at least the language to discourage the use of these roles for 99.9% of all cases should be much stronger in the spec or authoring practices. This is one of those things that gets totally misunderstood by web developers who are not as experienced in the finer points of accessibility nuances, and their use of these roles is often misguided by thinking along the lines of “it’s a popup, has to be a menu”. The situation is quite similar to the misuse of the “application” role, which also isn’t justified by just the fact that a web application is being created.

So as a TL;DR, I’d say: Don’t use menu* roles, they’re most probably inappropriate and cause more churn than a good user experience. Exceptions apply, but you’ll probably be told when they do. ;)