ScreenReader skips all links inside vertical list - html

I have an issue with using tab navigation or screen reader.
I have a bunch of divs with list inside of it, where each list item has a link, as shown in example below. This html represents vertical "carousel", where user can vertically scroll across the items.
The entire carousel is shown inside of popover (if it matters at all). And it has a lot of CSS to keep carousel scrollable(overflow:hidden, not sure if it matters).
While testing the widget for Accessibility, I found an issue:
Carousel container is not focusable when using tab navigation or screen reader. So, the entire container is just skipped by ScreenReader (Voice Over) and it never goes inside container to read the links.
I tried to add tabindex="-1" for the top most div element, and now it receives the focus, however, it doesn't go inside the div to go through the links.
What can be the reasons for that? How can I make VoiceOver not skip the content and go through all the links
<div class="a-carousel-viewport" id="carousel">
<ol class="carousel" role="list" aria-busy="false">
<li class="carousel-card" role="listitem" aria-setsize="12" aria-posinset="11" aria-hidden="true">
<div class="item">
<h4>Title 1</h4>
<a aria-hidden="true" class="a-link-normal vse-carousel-item" tabindex="-1" href="/someurl">
<div class="content">
</div>
</a>
</div>
</li>
<li class="carousel-card" role="listitem" aria-setsize="12" aria-posinset="11" aria-hidden="true">
<div class="item">
<h4>Title 2</h4>
<a aria-hidden="true" class="a-link-normal vse-carousel-item" tabindex="-1" href="/someurl">
<div class="content">
</div>
</a>
</div>
</li>
</ol>
</div>

It's hard to check the behaviour just from the HTML, a JSfiddle or CodePen to include the JavaScript would help a lot. However, you've got a lot of ARIA attributes that aren't necessary and might be confusing VoiceOver.
The first thing I'd try if you can't provide a demo of the problem behaviour is to remove all of the role and aria-attributes from your code sample and see if that fixes the problem. The roles for list and listitem are redundant on list (ol) and list item (li) elements. aria-setsize and aria-posinset are also not needed on lists. Tabindex and aria-hidden might be needed depending on how the carousel hides slides which aren't visible, but if removing the roles and aria-attributes doesn't help, it might be useful to remove them and see if VoiceOver can find the links when you do.

Related

What is a valid way to make a row on content clickable in terms of accessibility?

I'm trying to make a widget that can most easily be described as a clickable bootstrap media object list accessible. https://getbootstrap.com/docs/4.3/components/media-object/#media-list The original code has the js click event tied to the list item element itself.
My first thought was to wrap everything inside the list item element in a button element and attach my click event to the button. This gives the list item focus and acts how I would want it to. But then I read that it's bad practice to have things like divs or h tags inside a button tag.
<ul class="list-unstyled">
<li class="media" onclick="myFunction">
<img src="..." class="mr-3" alt="...">
<div class="media-body">
<h5 class="mt-0 mb-1">List-based media object</h5>
More info
</div>
</li>
</ul>
VS
<ul class="list-unstyled">
<li>
<button type="button" class="media" onclick="myFunction" disabled="isDisabled()">
<img src="..." class="mr-3" alt="...">
<div class="media-body">
<h5 class="mt-0 mb-1">List-based media object</h5>
More info
</div>
</button>
</li>
</ul>
So at this point is there another way to make the entire list item row clickable with semantic html, or is my best option to add role=button, onkeypress events for the spacebar and enter, custom active/disabled classes, and set tabIndex to the li tag?
Edit: Perhaps another way to think of the design is the with this component https://getbootstrap.com/docs/4.3/components/list-group/#links-and-buttons. Basically the design I'm trying to maintain is a stack of clickable rows, where each row contains an image and a couple short lines of text.
I don't see the point in having a heading within a button or a link. If you have a heading, it should represent the page structure.
You can easily solve your "problem" by wrapping the "More info" element in a button or a link. Keyboard users will be able to focus the button, and mouse users will be able to choose between the button or clicking on the whole list element wrapper.
<ul class="list-unstyled">
<li class="media" onclick="myFunction">
<img src="..." class="mr-3" alt="...">
<div class="media-body">
<h5 class="mt-0 mb-1">List-based media object</h5>
<button title="More info about List-based media object">More info</button>
</div>
</li>
</ul>
It all depends of how closely you want to follow the rules of semantic development and if you plan to support a page enabled for the blind and visually impaired.
The <a> should always be used for navigation from one page to another.
The <button> and <input type="button> should only be used to submit a form or for on-screen activities, like opening and closing a dialog, etc.
If you really want to follow the rules then allowing the user to click on an element other then buttons, input fields and select drop-downs is frowned upon. Screen readers, that are used by those visually impaired do much better if you use the correct element for the job.
Also, don't over do your DOM putting elements inside of elements without a good reason should be avoided. It just adds clutter.

Should I include the "menu button" inside the nav tags?

I have a simple question. Should the button, that I use to open/close my navigation menu be included in the nav tags?
The button itself is not helping in navigating but without him, there is no access to navigation.
<nav>
<ul class="nav">
<li class="nav__el nav__el-active">Home</li>
<li class="nav__el">Generic</li>
<li class="nav__el">Services</li>
<li class="nav__el">Blog</li>
<li class="nav__el">Contact</li>
</ul>
<i class="fas fa-bars"></i> //menu btn
</nav>
that's the example. Now the btn is in the nav, but it also can be like that:
<div class="topbar">
<nav>
<ul class="nav">
<li class="nav__el nav__el-active">Home</li>
<li class="nav__el">Generic</li>
<li class="nav__el">Services</li>
<li class="nav__el">Blog</li>
<li class="nav__el">Contact</li>
</ul>
</nav>
<i class="fas fa-bars"></i> //menu btn
</div>
At first glance, when reading this at WHATWG:
The nav element represents a section of a page that links to other pages or to parts within the page: a section with navigation links.
It seems to me that the button should not be included, as that's clearly not a navigation link.
Anyway, if you continue reading:
User agents (such as screen readers) that are targeted at users who can benefit from navigation information being omitted in the initial rendering, or who can benefit from navigation information being immediately available, can use this element as a way to determine what content on the page to initially skip or provide on request (or both).
With that in mind, it makes sense to include that button and any other non-link control you might have (usually in the header area) because if a screen reader user wants to...:
...skip the whole navigation, they also want to skip the other controls that are not links.
...jump straight to the navigation, they might also want to use some navigation elements that are not links.
If you check some of the examples at WHATWG, it looks like they are applying these criteria. The first example is:
<body>
<h1>The Wiki Center Of Exampland</h1>
<nav>...</nav>
<article>...</article>
...
</body>
Here, it makes sense not to skip the title on the page (to know where you are) but then skip all the navigation elements and jump straight to the content.
However, on the last one:
<nav>
<h1>Folders</h1>
<ul>
<li><a ...>... </a></li>
...
</ul>
</nav>
It would make sense to skip the Folders heading element if you are not interested in the navigation because it's actually part of it, the same way you put the heading of a section inside a section and not before it. The same applies to your menu button.
Some other examples of elements that might be part of the main navigation of the site, and thus go into <nav> are logos that link to the root of the site or search forms.
For example, LinkedIn is doing that:
Also, Bruce Lawson, who is part of the Accessibility Task Force, has the search inside the <nav> element on his personal website:
However, you can also find examples of the opposite. For example, AirBnB only includes some links in the <nav> element:
While in this case, I would have also included the search, that for me clearly represents the main way to navigate on their site.
Anyway, you could and should also use ARIA for accessibility and structured data / Schema.org markup for search engine support.

html <header role="menubar"> not validating on w3 validator

I have this main header element that is a page-specific navigation menu. As you can see the h1 element is a link to (the menu is fixed to the top of the page while the rest scrolls down).
Example:
<header role="menubar">
<a href="#top">
<h1>Main Title</h1>
</a>
<ul role="menu">
<li role="menuitem">
presentation
</li>
<li role="menuitem">
picture
</li>
<li role="menuitem">
downloads
</li>
</ul>
</header>
on w3 validator I get as message:
Error: Bad value menubar for attribute role on element header.
.
referring me to the W3 recommendation page for single pages where the allowed ARIA roles for the header element are:
banner role (default - do not set) or presentation.
.
'default - do not set' isn't really an option as it would not be backwards compatible because of the header element
'banner' and 'presentation' are not the correct roles (see banner and presentation)
So my questions:
What do I have to do? Easiest would be to replace the header element
by a div element. But I think it is semantically less good, is that
right?
Is it possible that this case was not really considered by the W3C
people or is it 100% wrong to do so (I mean on a semantic level
focusing on accessibility).
Are there other options?
thank you :)
What your current code shows is not a menubar but a navigation list. Instead of <header role="menubar"> you need <nav> and you should remove the role attributes from the list elements. If you are implementing a menu bar, your code is very incomplete.
For advice on using HTML5 and WAI-ARIA for menu bars, see Recommended WAI-ARIA implementation for navigation bar/menu.

Semantic markup of navigation and search area

I'm trying to learn semantic HTML5 markup by converting a simple site I once made for an old magazine. Now I've come to the navigation and search area. You should be able to select a specific article to read or search within the database. There are two tabs and when the first one is active you see the contents of the selected issue like this:
When clicking on the search tab you come to a search field, like so:
And when you've made a search the results are presented in a similar fashion to the contents above:
The present markup looks something like this:
<div id="nav">
<div id="tabs">
<div class="tab">Browse</div>
<div class="tab">Search</div>
</div>
<div id="browse">
<form>
<div>
<label>Year:</label>
<select>
<option>1985</option>
</select>
</div>
<div>
<label>Issue:</label>
<select>
<option>1</option>
</select>
</div>
</form>
<div id="contents">
<h1>Contents</h1>
<ul>
<li><a>Lorem ipsum</a></li>
</ul>
</div>
</div>
<div id="search">
<form>
<label>Search for anything:</label>
<input type="text">
<input type="submit" value="Ok">
</form>
<div id="results">
<!--
<h1>Sorry, we couldn't find anything.</h1>
<ul>
<li><a>Various stuff</a></li>
</ul>
-->
</div>
</div>
</div>
As for semantic elements, I have considered various options, none of which seems like the solution.
My first problem is whether I should wrap the whole thing inside nav tags or just the browse part, or even just the contents part of the browse part. I'm somewhat inclined to consider the whole thing a single main navigational area.
As for the inner parts, I assume they could be divided into section elements, primarily a browse section and a search section. If so, it would have been nice to get the tab text into those sections as headings, but that will complicate things presentational-wise too much (I know I shouldn't worry about CSS and JS at this stage, but I do). And sections without headings seem like a bad idea.
Another option would be to regard the div#contents and the div#results as subsections. One problem with that is that the results area doesn't have any content until a search has been made.
I can think of some other options as well, but I don't see any point in mentioning them all just to show research effort. I would still need just as much help. And I'd appreciate it too.
My first problem is whether I should wrap the whole thing inside nav
tags or just the browse part...
Looking at the definition of the nav element in the HTML5 spec
The nav element represents a section of a page that links to other
pages or to parts within the page: a section with navigation links.
...tells us that it should be used for the id="browse" element.
I think it should also wrap the form because it contains controls to filter these navigation items.
The id="search" element should, according to the aria role search
A landmark region that contains a collection of items and objects
that, as a whole, combine to create a search facility.
Get a role="search".
The tab list on the top should get the proper aria treatment for tabs with role="tablist" and role="tab". As shown in this snippet:
<div id="tabs" role="tablist">
<div class="tab" role="tab" aria-controls="browse">Browse</div>
<div class="tab" role="tab" aria-controls="search">Search</div>
</div>

Adding role=document to div causes JAWS to read "clickable"

I'm working on an application that displays a list of chats and need to get the chats into the virtual buffer. The chat content can be as simple as a line of text or as complicated as text plus a link plus an image. Without role=document, it's not in the buffer but with role=document JAWS reads "clickable" when it reads the content (after pressing down arrow). The content is not clickable and I can't figure out how to stop that from being read.
Here's an example of the layout:
<div role="application" class="mainViewContainer">
<ul class="mainViewContent">
<li tabindex="0" class="chatViewContainer">
<div tabindex="-1" class="chatHeaderContainer">
<span class="offscreen" id="chat1">Chat content</span>
<div role="document" tabindex="0" class="chatContent" aria-labelledby="chat1">
Here's a message, huzzah!
</div>
</div>
</li>
<li tabindex="0" class="chatViewContainer">
<div tabindex="-1" class="chatHeaderContainer">
<span class="offscreen" id="chat2">Chat content</span>
<div role="document" tabindex="0" class="chatContent" aria-labelledby="chat2">
<div class="chatText>Document documentName.jpg created </div>
<div class="documentView">
<img title="documentName.jpg" src="imgsrc">
<div class="documentItemDetails">
documentName.jpg
</div>
</div>
</div>
</div>
</li>
</ul>
</div>
Any ideas on how to make the chatContent div not have "clickable" read by JAWS?
I'm seeing this with JAWS Version 15.0.6025 (I believe it's the most recent version) and FF 26 on Windows 7.
I had this same issue. Apparently, this is an expected behavior, as explained in this URL.
Clickable Text : When you navigate to a grid cell that has its display style set to clickable text, JAWS reads the corresponding column header text and then the data content of the current cell.
I hope this helps.