jquery-ui tab "Interactive controls must not be nested" - accessibility

I use jquery-ui tabs. Sample code:
<ul role="tablist">
<li role="tab"><a class="label" href="#tabs-1" aria-label="Description tab">Description</a></li>
<li role="tab"><a class="label" href="#tabs-2" aria-label="Reviews tab">Reviews</a></li>
<li role="tab"><a class="label" href="#tabs-3" aria-label="Credits tab">Credits</a></li>
<li role="tab"><a class="label" href="#tabs-4" aria-label="Cataloging tab">Cataloging</a></li>
</ul>
The axe-core DevTools accessibility checker flags a "serious" problem with this code: "Interactive controls must not be nested", with the explanation "Interactive control elements must not have focusable descendants" and referencing guideline WCAG 4.1.2.
The problem, as I understand it, is that there is a link inside the listitem. From a Github discussion for axe-core (https://github.com/dequelabs/axe-core/issues/601), the clickable link within the list item causes issues with screen readers.
But this seems like a standard use of the jquery-ui tab widget. How I do change the tabs widget code to make it accessible?

The items within <ul role="tablist"> will have tabindex="0" etc. added to them in order to make them focusable (the actual li, not the link) and then the anchor should have tabindex="-1" added to it.
The idea is that the link is a fallback for if JS fails, this is why it is included in the first place and isn't just plain text.
However this does indeed cause nesting of interactive elements as you now have tabindex="0" on the list item (making it "interactive" / focusable) and then a link within it.
They add tabindex="-1" to the link to remove it from the focus order, but some screen reader / browser combos will still pick this link up and this is why it is flagged.
So there is a workaround but you will need to implement it yourself.
First, add role="none presentation" to the link:
<li role="tab"><a class="label" href="#tabs-1" role="none presentation">Description</a></li>
What this does is signal that this anchor should be treated like a <div> or a <span> as far as assistive technology is concerned (it removes all semantic meaning).
Secondly, (but you would have to check it works with jQuery-UI) would be to remove the href attribute from the link via JS (so it is only removed once the Tab component has initialised).
You should end up with the following if you inspect the elements after doing this (ignoring any classes added etc.):
<li role="tab"><a class="label" role="none presentation">Description</a></li>
This will stop it being a focusable item if JS works and loads correctly, but will fall back gracefully if JS fails to load.
Also notice I removed your aria-label as the fact you are using a role="tab" already tells a screen reader that it is a tab so your label was not needed.
So in summary:
add role="none presentation" to the links within the <li>
remove the href attribute from the links via JavaScript.
remove the aria-label (not related to the problem)
This should make the tabs as accessible as possible within jQuery-UI, but there may be other problems with it so I can't say whether it is accessible or not!

Related

How to retain the background color when i hover to sibling using CSS

I have build a dropdown menu that works a sweet as it gets.
Right click on an element, brings up he dropdown menu, i hover over the first choise, soo far so good, the font color and the background color changes as it should and the sub-menue opens. The problem is that when i hover over the sub-menu, the i "loose" the gray background color of the "parent"
Any ideas ?
<div id="contextMenu" class="dropdown-menu" role="menu" style="display: block; left: 997px; top: 438px;">
<ul class="dropdown-menu side" role="menu" aria-labelledby="dropdownMenu" style="display:block;position:static;"><li class="dropdown-submenu"><i class="fa fa-paste" aria-hidden="true"></i> PARENT OPTION <ul class="dropdown-menu"> <li> <a tabindex="-1" data-url="/common/docitem/copymove/?document=247&dest=1&obj_table=companydocument&f=null" id="add_id_copy_p" style="cursor:pointer;" class="js-movecopy-docitem"> Siblin Option</a> </li>
First things first, you must include a code segment to make it easier to understand the issue, as #Paulie-d and #Rokibol Hasan mentioned. To be honest, this sounds like maybe you have conflicting CSS rules or lack of specificity, which results in your parent element being affected on :hover.
These would be the steps I would use to solve this:
Use the find function of your development IDE (CTRL + F) to find :hover elements. Avoid using very broad CSS selectors.
Make sure you have assigned the correct id and class attributes in the desired section of code.
Refresh your memory on CSS specificity. I provide you this website instead of Mozilla only because I do not know if you can handle it. If you are experienced, prefer this website.
Refresh your memory on CSS selectors.
At this point, go in your CSS and start commenting out and testing one by one sections of code that may affect the parent element you speak of.

Trying to understand aria and accessibility

I'm updating a website, doing an iterative improvement on the accessibility.
I'm using multiple tools to get the pages better: FireFox's accessibility tree viewer; Chrome's lighthouse checker; the "wave" accessibility tool, and I'm trying tenon.io
(sadly, I don't have access to a decent screen reader - nvda is too fast for me to hear, orca seems to read the current line, and I don't have access to JAWS)
So here's what I have:
I have a navigation structure like this:
<nav aria-label="Main navigation">
<section class="desktop-navigation" aria-label="Main Menu">
<ul aria-label="Menu items">
<li>About Example</li>
<li>Documentation</li>
<li>Pricing</li>
<li>Status</li>
<li>Contact us</li>
</ul>
</section>
<section class="main-nav-wrapper" aria-label="Header logos">
<a href="/"><img src="/images/logo_example.svg?v=488a8c6971df396baaa401bb073b4a6b"
class="header-logo" alt="The Example logo" aria-label="Example Logo"/></a>
<div class="site-logos-right" aria-label="Corporate Logos">
<a class="external-link" href="https://www.example.com/" rel="external"><img
src="/images/logo_company.svg?v=98693292e027eca1f27cfc89b68a77d2" class="company-logo"
aria-label="The Company logo" alt="Official logo for Company"/></a>
<a class="external-link" href="https://example.com/department"
rel="external"><img src="/images/logo_department.svg?v=ff0114bb2ebf7eff339341f9554220d0"
class="edina-logo" alt="Official Department logo" aria-label="department logo" /></a>
</div>
</section>
</nav>
..... and this is 100% according the lighthouse, but tenon.io is reporting an issue (multiple times) and I don't understand why:
This element uses multiple strategies to create labels
This element has more than one possible label. The manner in which the
accessible name is calculated for controls uses an algorithm in which
only one of these labelling approaches will win. This means one of
these labels will be ignored by assistive technologies. There should
be only one label provided and the others should be removed.
Examples of items identified:
<nav role="navigation" aria-label="Main navigation">
<section class="desktop-navigation" aria-label="Main Menu">
<ul aria-label="Menu items">
<li><a href="/" aria-label="Return to the home page to read about
(I notice that the W3C site does not label the uls - but then they show as un-named elements in firefox)
I definitely want to label landmarks & sections.... so what's it actually complaing about?
<li>Pricing</li>
.... this is an example of where I want to have a more descriptive label for the element - when scanning the accessibility tree, just having the bare link-text doesn't (to me) read as well as having some context: as a sighted user, I know my eyes have flicked over much of the page, and seen additional text, so subconsciously have some context for the menu items.
My question(s)
How is the accessibility label computed?
Why can't I have a more descriptive label on a link? (lighthouse complains if the alt text doesn't contain the link text... but is happy if it's more than the link text) - or is this tenon.io being over-picky?
The accessible name computation is how accessibility labels are computed.
You're using aria-label too much, and the result may be difficult to listen to or outright confusing for human visitors using assistive technologies.
The first rule of ARIA is don't use ARIA unless you really have to.
It is appropriate to use aria-label on the <nav> and <section> elements. Keep that.
I can't think of any good reason to use aria-label on a <ul> element. I'd recommend removing that.
Using aria-label on anchor elements is normally unnecessary and should be approached with caution. Unless you have a really good reason, you probably shouldn't be presenting different content to visitors using assistive technology.
I would also recommend removing aria-label from your images. This is exactly what alt text is for.
If you really want to use aria-label on anchor elements, WCAG has some guidance:
Per the Accessible Name and Description Computation and the HTML to Platform Accessibility APIs Implementation Guide, the aria-label text will override the text supplied within the link. As such the text supplied will be used instead of the link text by AT. Due to this it is recommended to start the text used in aria-label with the text used within the link. This will allow consistent communication between users.
https://www.w3.org/WAI/WCAG21/Techniques/aria/ARIA8.html#description
Don't give up on NVDA just yet. I also found the default speech settings too fast and difficult to understand. You just need to adjust the settings. The voice can also be changed out for better ones. It takes a bit of work to configure, but in my opinion NVDA is the best free screen reader available today. VoiceOver is also very nice if you have access to Mac/iOS products.

accessibility menu - open menu on focus

in my site i have menu and sub menu
my problem when i focus by tab to the menu, the menu opened like i hovered the menu by mouse.
but when i continued to the sub menu elements with tab the menu closed.
how can i keep the menu open if some of sub element is focused.
of course i can do it via javascript, but i want to know if i can do it with css only.
here is example (try go to links with 'tab' )
li.main{
float:left;
width:200px;
}
li .sub{
display:none;
}
li:hover .sub{
display:block
}
li.main:focus .sub{
display:block
}
<ul>
<li class="main" tabindex="0">
First menu
<div class='sub'>
<ul>
<li>First Link </li>
<li>Second Link </li>
</ul>
</div>
</li> <li class="main" tabindex="0">
Second menu
<div class='sub'>
<ul>
<li>Third Link </li>
<li>Forth Link </li>
</ul>
</div>
</li>
</ul>
With the current possibilities of CSS, you can't, as it was discussed in a lot of questions before (see accessible css dropdown menu for instance).
First of all, you can't use "display:none" in such approach because the link can't be accessed using the next link shortcut (tab key in most of the browsers implementation).
Solutions which work will imply solutions like positioning out of screen. It will restrict the view on screen to the current link as there is no parent() selector in CSS, or you might use a trick like in the above thread (which will work in some browsers and limit the width of the dropdown part).
But no matter the solution, it will not resolve the main problem : a dropdown menu is not the best way to achieve accessibility.
For instance, people with disabilities using eye tracking software will never benefit of a dropdown menu. Neither will people using tablet.
It is always something difficult to use, difficult to understand : What if I click on the category link? Does it open the category main page, or does it open the submenu?
If you really want an accessible menu, do not use a dropdown menu

ARIA label for menu widget not read

UA: Mozilla Firefox 28.0;
AT: JAWS 14.0.1534 and NVDA 2014.1;
OS: MS Windows 7 Professional SP1
Given the following simple ARIA-enhanced menu widget, why is the associated 'Where to go' label never read? It's been my understanding that labels associated with focusable elements should be announced when focus is received. Instead, only the menu item's text is read.
<div role="application">
<ul id="main-menu" role="menu" aria-label="Where to go" aria-activedescendant="item-1" tabindex="0">
<li id="item-1" role="menuitem">First page</li>
<li id="item-2" role="menuitem">Second page</li>
<li id="item-3" role="menuitem">Third page</li>
</ul>
</div>
Is it some kind of "optimization" as to prevent excessive information to be read to the user everytime the menu received focus? Like, the contents of the "menuitem" would be prioritized over the labelling of the containing menu widget. Of course, this is just a wild guess. Does anybody have more details that could help clarify the above situation?
A related question based on the same code sample: I've found out that doing away with the containing div (the one with the role="application" attribute) changes absolutely nothing regarding the behavior of the widget (there's Javascript code for controlling keyboard interaction and updating the UL's aria-activedescendant attribute). When do you actually need a container with role="application"?
Based on the example, it doesn't look like something that should be a menu.
The menu role is intended for application style menus which pop-up sub-menus. See this menubar example.
Upon tabbing to the menu, you then use arrow keys to navigate, not tab.
What you've got (so far at least) is simple navigation, and on a website the most appropriate mechanism is standard links.
<nav aria-label="Where to go">
<ul id="main-menu">
<li>First page</li>
<li>Second page</li>
<li>Third page</li>
</ul>
</nav>
The aria-label may or may not be read out by a screenreader (in a brief test NVDA did not, VoiceOver did), if that is important hide an off-screen heading above the menu. However, that label is used if the user navigates by "landmark".
If you do go for a full menu, I'd try the accessible Adobe mega-menu.

How to Override Browser Remembering Position when loading a new Version of a Page?

I have a page called results.aspx. It shows a list of search results. I have a transport (for want of a better term) at the top and bottom of each page. One of these:
Previous 1 2 [3] 4 5 Next
Each of the text elements in the transport has a link in it, like this:
<a href="results.aspx?page=4" />
Page number varies, of course, based on the intended destination.
My problem is that because the root page name is the same, results.aspx, the browser always scrolls to the same position on the newly loaded page as it was on the page I just clicked away from. Or at least that's what I'm assuming is happening.
I've tried to create tags like
<a name="top">
<a id="top">
and change my link to either of
<a href="results.aspx?page=4#top" />
<a href="results.aspx#top?page=4" />
To no avail. I should point out that this is an inherited code base, so there could be nasties in the javascript that are overriding default behaviors.
Is there an obvious way to fix this? If it should be working by default, is there something in the code that I should be looking for that I should change or remove?
-- EDIT --
Here is a sample of the generated code taken from a browser:
<!-- Page Transport -->
<ul>
<li class="gray">first</li>
<li class="gray">previous</li>
<li class="current">1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>next</li>
<li>last</li>
</ul>
Yes, they're just hrefs and for the life of me, I cannot figure out why a browser would remember its position on the page!
-- SOLUTION --
Turns out the original developer included a javascript file, scrollsaver.min.js, which deliberately implemented this behavior. Removing this reference eliminated the behavior.
Are you sure that those links are <a> tags and not buttons or <a> tags with onclick. If they are plain <a> tags what you describe should not happen. If those are postback buttons, somewhere in the code the scroll position is maintained by using MaintainScrollPositionOnPostback. Search for it. Once you can confirm that it is used, you can use Resetting Scroll Position to overcome this.

Resources