In the comments on my previous blog post, Adrian Roselli called me out for my claim that the "menu" design pattern in the W3C's WAI-ARIA Authoring Practices is the right way to code a navigation menu. This is an issue that has plagued me for at least a decade, maybe more. My first blog post on the topic, Accessible Dropdown Menus, was published in March 2012. I followed that up in December 2013 with Accessible Dropdown Menus Revisited, still searching for the holy grail in accessible web navigation menus, but liking what I found in Adobe's Accessible Mega Menu.
Based on these two old blog posts, I've had many people contacting me over the years asking for advice about accessible navigation menus. In recent years, I've always referred them to the WAI-ARIA Authoring Practices. On GitHub, this resource refers to itself as WAI-ARIA: Authoring Practices Guide and is commonly referred to by the acronym APG, so I'll use that here for brevity. The APG contains dozens of design patterns for common web widgets, including a recommended keyboard model and ARIA markup for each. I've always believed that in order to attain a consistent user experience for common widgets across the entire World Wide Web, we need a central source of standard, recommended design patterns; and from my perspective, APG was that source. I have encouraged developers to keep the APG handy, and when they're about to create a widget, check to see if there's a recommended design pattern, and use that. Developers have followed this advice, and when they've wondered how to create a navigation menu (for example), they've gone to the APG, looked for a "menu" design pattern, found exactly what they needed, and simply followed the recipe. However, there's confusion around menus specifically, which has led me to question how zealously I should recommend the APG.
The source of my confusion is that there are actually several design patterns for navigation menus. I'll summarize the three I know about (or four, depending on how you count them):
- Menu or menu bar
This is the design pattern I linked to in my previous blog post. It uses a set of menu-related ARIA roles (menu, menubar, menuitem, etc.), plus relevant attributes (aria-haspopup, aria-expanded, tabindex, etc.) and includes an extensive keyboard model that replicates the menus encountered in desktop applications. In fact, many would argue that it should only be used for application menus (think Google Docs), not for web navigation. However, the APG accompanies this design pattern with a Navigation MenuBar Example, which suggests that it's a good fit for this purpose.
- Disclosure (Show/Hide)
This too includes an Example Disclosure for Navigation Menus. It's a much simpler design pattern, with comparatively little ARIA (no roles, just leaving the native semantics of list items and anchors intact; and the only attributes are aria-expanded and aria-controls). Above the example is a checkbox that can be toggled on to include support for arrow keys, Home, and End, but these are considered optional. Essentially that optional enhancement makes this design pattern two design patterns; hence, four total patterns.
- Fly-out Menus
This is actually one of the Web Accessibility Tutorials, not part of the APG, so it's a separate resource but it comes from the same organization, the W3C Web Accessibility Initiative, so I expect some harmonization between the recommendations. The tutorial is more similar to the "Disclosure (Show/Hide)" design pattern than the "Menu or Menubar" design pattern, but it nevertheless differs in some key details (e.g., the top-level menu item has aria-haspopup, and in the example that uses a button as toggle, aria-expanded is used on both the anchor and button). These discrepancies might be addressed in the future, as there's an active GitHub issue to Align Menus Tutorial with ARIA 1.1. For now though, it's another distinct model.
Which of these design patterns should developers use? From my experience, most latch on to the first one, because it's a "menu", and that's what they call the thing they're creating. I've never heard a developer use the word "disclosure" when referring to their navigation menu, so that pattern is not so easy to discover.
But hold on. Is a menu really a menu?
Some would argue that it isn't. In the Inclusive Components article Menus & Menu Buttons (May 10, 2017), Heydon Pickering makes a compelling case that navigation menus are not "menus"; they're lists of links, essentially functioning like a website's Table of Contents. Colloquially we've come to refer to them as menus, but the only thing that makes them seem menu-like is styling, not their underlying semantics.
Others have written blog posts about this, and all seem to agree that a navigation "menu" is not really a menu.
- From Adrian Roselli: Don’t Use ARIA Menu Roles for Site Nav (Oct 2017)
- From Marco Zehe: WAI-ARIA menus, and why you should handle them with great care (republished in May 2019)
- From Marcus Hermann: Menu (or not) (June 2019)
On top of that, there have been exhausting discussions about this and related topics in the Issues forum for the APG GitHub repo. Yesterday was a UW-IT "No Meeting Friday", when we're given the freedom to disengage from the usual grind and focus on something of particular special interest. I spent most of the day reading through those discussions, and I'm still at it now on Saturday morning. Here are some highlights, if you're inspired to take a deep dive:
- Clarify Purpose of Menu Navigation
- Disclosure menu example
- Project page for Menu, Menubar, and Menu button - the complete set of relevant issues
- Stronger support / testing / best practices text on every example - not related to menus specifically, but relevant for addressing the source of my confusion about APG
So... what to do?
My purpose in writing this post is to clarify, not to confuse. To that end, here are my key takeaways from all this:
- The APG is informative, not normative. The design patterns are not standards, not even recommendations in a formal sense. They're simply examples. It's still good to consult them when determining the best way to code something, but consult other sources as well, and if you're unsure, ask someone.
- Remember the First Rule of ARIA: Don't use ARIA, if the underlying HTML is sufficient for communicating what this thing is. In the case of a navigation menu, that's a nested list of links. The HTML <ul>, <li>, and <a> elements all have built-in functionality and accompanying user expectations, so we shouldn't override that with role="menu" and the like.
- The Link + Disclosure Widget Navigation design pattern documented by Adrian Roselli (June 2019) seems like the best fit for most web navigation menus that I deal with in a university context. It's a better fit than the APG Disclosure (Show/Hide) example because it accounts for the top-level menu item being a link, which I'm told is not optional on the UW website. And it's better than the WAI Flyout Menus Tutorial because the latter is just a tutorial, and isn't quite aligned properly with ARIA 1.1.
Please don't take anything I've said here as The Truth. And don't be surprised if I change my mind again, as there's precedent for that. Also I'm wide open here for corrections, clarification, or disagreement, so feel free to comment.