This morning I woke up to some great advice from @heydonworks:

Per a later conversation with @SaraSoueidan on this topic, and the responses indicated there were many who did not quite grasp the full significance of the example, and why placing the button inside the navigation landmark was important.

Discoverability is key

What people were primarily focusing on was the button’s placement and how that would affect the design, the way they’d need to code the CSS to target the navigation’s <ul> instead of the <nav> itself. Why couldn’t they just put the button somewhere else in the DOM and use aria-controls to point to the navigation?

To all of that I’d respond…

“What navigation?”

The issue isn’t that the button needs to be near or within the navigation to reveal it to the user. With JavaScript, a button could be located at the bottom of the DOM and still open a navigation at the top of the DOM.

The issue is that correctly hiding a navigation by default, whether that be done with display: none or visibility: hidden, not only removes it visually from view, but also removes it from being discovered by assistive technologies (ATs), e.g., screen readers.

You see, users of ATs don’t just start feverishly tabbing through an interfaces just hoping to find what it is they’re looking for. Well. Maybe they would if they were trying to prove a point about how horrible a site was coded. But yeah. Not really.

Typically when an AT user comes to a page, they do what sighted users do. They do a quick scan of the page. Obviously their method of doing so is different. While sighted users can quickly just look around a page and determine functionality and relationships by appearance, a fundamental way for AT users to determine a site’s structure and significance is by its structural makeup, such as what landmarks (topical!) and headings are available (There are other methods as well, but let’s just stay on topic).

Looping back to the hidden navigation, this is where the problem arises and Heydon’s example is the solution.

Hiding the <nav> removes it from the landmark listing. So AT users would come to the page and on initial review could only determine “Oh. This page doesn’t have a designated navigation region. Well. This should be fun…”

It’s not that the navigation couldn’t or wouldn’t eventually be discovered. The issue is that there would be no easy access to it. A user would have to learn that the element to open the navigation was in a particular location in the DOM. Remember that location. Navigate to and through that location as necessary. Activate the element to expose the navigation, and then they would finally be able to enter it and access the necessary content within.

By placing the button to reveal the navigation within the navigation landmark, and instead hiding the rest of the navigation’s contents (whether that be the primary list element or a <div>s surrounding multiple components of the navigation), the navigation never gets hidden from ATs</code> and can be easier to discover.

<nav> 
  <!-- 
    the landmark is always exposed if it's the listing 
    of links withi that has its display toggled.
  -->
  <button aria-expanded=false>
    Reveal navigation
  </button>
  <ul syle="display: none">
    ...
  </ul>
</nav>

So what are the takeaways here?

Mainly, this is more about being mindful with how our documents are setup and what we reveal (or don’t) to all users with our document structure and CSS.

Including the button within the navigation allows for the navigation landmark to exist and to always have discoverable content within it (the button). The button then would be used to control the visual state of the navigation’s contents, via JavaScript, CSS, and with aria-expanded to communicate whether the content is displayed (expanded) or hidden (collapsed).

The high level intent may be to visually hide a navigation from view, until a user specifically wants to interact with it. But the overall intent is likely not to obscure the fact that a navigation exists.