0

I'm trying to figure out a accessible way to hide/show content such that when the content is hidden, screen readers can still "see" it but keyboard users aren't forced to tab through invisible links.

Consider something like the following:

<button onclick="(function(e){ document.getElementById('nav').classList.toggle('active') })()" class="menu-toggle">Toggle Menu</button>
<nav id="nav" class="nav">
<a href="#home">Home</a>
<a href="#about">About</a>
<a href="#contact">Contact</a>
</nav>

If you want to see it in action with the CSS I created this codepen.

The problem I'm trying to solve is that when the menu is hidden, a keyboard user will still tab through the hidden links. I'd like to prevent that behavior in a way that doesn't make the links invisible to screen readers (ex: display: none;).

I also don't want to duplicate the menu markup in a second "screen reader only" copy. Any other ideas are welcome.

emersonthis
  • 32,822
  • 59
  • 210
  • 375

2 Answers2

3

I'm trying to figure out a accessible way to hide/show content such that when the content is hidden, screen readers can still "see" it but keyboard users aren't forced to tab through invisible links.

Screenreader users are (mainly) keyboard users, so removing keyboard usage for them is not an option.

On then other hand, some screenreader users with low vision may still use their mouse. By announcing a link not visible on screen, this will lead to accessibility problems for people which won't be able to view and click on an announced link.

Adam
  • 17,838
  • 32
  • 54
  • Right. You've restated the problem I'm trying to solve. But this isn't actually an answer. – emersonthis Dec 24 '17 at 17:50
  • 1
    @emersonthis You misread my answer which give you a definitive answer. The thing you want to achieve is clearly not an option. I won't and I can't promote something that is clearly not accessible and impossible to achieve. – Adam Dec 25 '17 at 17:34
1

Here is a rough codepen showing how you can do this

By setting and removing tabindex from your links, keyboard users will bypass them unless the function is called. When the function is called we focus on the first link so the user is taken to the spot they should be at.

function clickButton(){  
  var nav = document.getElementById('nav');

  if(nav.classList.contains("active")) {
    nav.classList.remove("active");
  } else {
    nav.classList.add("active");
    if (nav.hasChildNodes()) { 
      var children = nav.getElementsByTagName("a");
      for (var i = 0; i < children.length; i++) {
        children[i].setAttribute("tabindex", "0");
        children[0].focus();
      }
    }
  }
}

I also don't think using Javascript to set display:none and display:block on trigger is a bad way to handle this. If content is made visible on the page with JS, a screen reader will know (See this SO post). If we focus on the first item in the nav after it appears, there shouldn't be any confusion or loss of content. Tabindex is a fine way to handle this though (See the other link in the comments for more info), I just don't think display:none here is as bad as you think it might be.

You might be concerned about non-JS users. First, it's reported that over 98% of screen readers render JS, so it's safe to argue JS approaches are going to cover almost all of your user base. However I understand and merit concern for it still which in that case, you could use a few different methods to check for no javascript and apply overriding styles for that specific group.

Here's more on the topic from W3 with some examples.

Stu Furlong
  • 3,490
  • 5
  • 34
  • 47
  • I hear what you're saying about "trusting" the screen reader to figure out the content that's being toggled with `display:none;`. My thinking is mostly that it's annoying for a low vision user to have to toggle the links on and off. Do you have any thoughts on that? Maybe I'm wrong in my thinking. – emersonthis Dec 24 '17 at 17:58
  • I don’t think it would be any more or less annoying than it would be for any normal keyboard user. If you only have 3 links in the nav being toggled that might be overkill and something to consider during the design phase, but for a nav with a ton of links - I think this is actually a convenience to be able to pass without relying on getting to the skip to main link. Bottom line is I don’t see it as a problem. – Stu Furlong Dec 25 '17 at 21:47