Reputation: 33348
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.
Upvotes: 0
Views: 2888
Reputation: 3629
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.
Upvotes: 1
Reputation: 18807
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.
Upvotes: 3