Button is not accessible and not focused on tab key - html

I have below code to show buttons in a multi select dropdown. I have used tabindex="0" for each tag. Also added focus in CSS.
.btn-clear-all:focus {
outline: -webkit-focus-ring-color auto 1px;
outline: 1px solid black;
}
<div class="form-group-multi__MultiControls">
<p tabindex="0" class="btn-tertiary--light">Cancel</p>
<p tabindex="0" class="btn-clear-all">Clear all</p>
<p tabindex="0" class="btn-secondary">Apply</p>
</div>
My problem here is 'Cancel' button is accessible on tab key, but not other two - Clear all and Apply.

You are missing an extremely obvious thing (I mean, for semantics and accessibility).
Look at your buttons and pay attention to what you see. Do you see buttons?
Correct answer: No. You see paragraphs (<p>s, not <button>s).
There are two solutions, one best and one not so good:
The best solution. Change all of your <p>s to <button>s. You already have Bootstrap's btn-secondary class applied to them, so I'm pretty confident your styling won't suffer in any way.
Add role="button" to your <p>s. Again, as the first rule of ARIA states that you mustn't use ARIA if you absolutely haven't to, it's a not too good solution.

Related

Accessibility error 'Text not included in an ARIA landmark'

I have a button which opens a calendar modal, I know calendars are bad for accessibility but my client insists on it. This is the code that opens that calendar modal.
<div class="col-sm-6 hidden-xs text-right calendar-cta">
<a type="button" onclick="openNav()" href="#" class="btn-primary">Calendar view</a>
</div>
I then have a close button on the model, which is where the accessibility error is being produced. The x is showing up as 'Text not included in an ARIA landmark'. What am I doing wrong? What do I need to add in order for this to stop producing the accessibility error. Any help would be hugely appreciated.
<div id="myNav" class="overlay" role="menu">
<a class="closebtn" tabindex="-1" role="menuitem" aria-label="close calendar view">×</a>
<div class="overlay-content"> </div>
</div>
This is more of a warning than an error. It's not required under WCAG, although it is best-practice, and you should try to do it if you can.
It is a best practice to include ALL content on the page in landmarks, so that screen reader users who rely on them to navigate from section to section do not lose track of content.
https://www.w3.org/WAI/WCAG22/Techniques/aria/ARIA11
You should ideally be using HTML semantic sectioning elements, like: <main>, <nav>, <aside>, <header>, <footer>, etc. This warning is saying that all rendered content should be in some sort of containing element that has an ARIA role associated with it.
There's a great chart that maps all of the HTML 5 semantic elements to their implied ARIA roles.
I'd also recommend changing your a.closebtn to a button element and removing tabindex="-1". Since you're not navigating to a different location, but rather doing something that causes a change to the UI, I think that a button is a more appropriate choice. The tabindex attribute isn't necessary and only serves to prevent receiving focus by manually tabbing.
The direct and the short answers to the questions:
What is wrong here is that aria-label does not contain the visible text and it is a concrete WCAG failure under 2.5.3 Label in Name. Why and how it fails is explained under Failure due to the accessible name not containing the visible label text
Two quick and dirty solutions:
Write "close calendar view" instead of "x" if possible and remove the aria-label attribute
Hide the "x" sign from ARIA by putting it inside <span aria-hidden="true">x</a>. The one and only thing the screen reader will read will be "link close calendar view".
The "Text not included in an ARIA landmark" may still show up, it is a false positive when it is hidden from ARIA.
However, the above fix will fix only 2.5.3, but there are more important issues here.
I wonder
Why the role="button" was assigned to an anchor element to make a button, when there is the button element readily available and no link to anywhere was intended.
From Bootstrap:
When using button classes on elements that are used to trigger
in-page functionality (like collapsing content), rather than linking
to new pages or sections within the current page, these links should
be given a role="button" to appropriately convey their purpose to
assistive technologies such as screen readers.
What tabindex="-1" does there. It will remove the button from the tab order and the keyboard user will not be able to reach or operate it. It causes a concrete 2.1.1 Keyboard failure.
Why closing the calendar view button has a role="menuitem". Is there a menu there?
Moreover, the usage of the "x" character as the only visible accessible name of a button is a 1.3.3 Sensory Characteristics failure. It is an assumption that all users know "x" denotes "close". Just like not everyone understands an asterisk denotes "required fields", ">" sign means "next", or 3 bars on top of each other is now a menu called "hamburger menu". These should all have some textual explanation. Aria label makes the explanation for the screen reader users but some sighted users may still fail to understand what is meant there.
Alternative code, not including how the btn-close works: (Close button Bootstrap v. 5.0)
(Please note that Bootstrap does not address the 1.3.3 criterion explained above, that is why I included a tooltip in my suggestion.)
<div class="col-sm-6 hidden-xs text-right calendar-cta">
<button type="button" class="btn-primary" onclick="openNav()">Calendar view</button>
</div>
<div id="myNav" class="overlay">
<button type="button" class="btn-close" aria-label="Close calendar view" title="Close"></button>
<div class="overlay-content"> </div>
</div>

How to label a loading animation for WAI-ARIA?

I'm working on fixing some accessibility issues on a web page. I have this div that acts as a dialog, and inside at one point a div containing a loading animation and a text "Working..." is displayed.
I am unsure as to how to label these two items in order to correctly notify the blind user that there is a progress animation and that it's working and he should wait.
<div id="loading" style="display: none;">
<div class="mgBot15"><span class="txt16" role="alert">Working...</span></div>
<img src="loading.png" role="progressbar" aria-busy="true"/>
</div>
I tried adding the role and aria-busy properties to the img (also to the parent div, at first).
When this div appears (by changing the display style property), it correctly reads "Working..." but I hear no indication that it's busy and that the user should wait, am I missing something?
I've looked all over for examples for loading animations, to no avail so far.
Note: I'm using NVDA as a screenreader to test.
Thanks
The best solution I could come up with was using role alert, and aria-busy="true".
<div id="loading" style="display: none;">
<div class="mgBot15"><span class="txt16" role="alert" aria-busy="true">Working...</span></div>
<img src="loading.png" alt="loading" />
</div>
I believe the most sensible approach would to use the combo
aria-busy="true" aria-live="polite"
The reason for that is because some pages might have a lot of separate loaders (let's say one for each component, not a single loader for the whole page) and it you use aria-live="assertive" or role="alert" it will be very intrusive and each of the loaders will get called out.
The correct role to use here is progressbar as the original question used. Other roles like alert may work, but they are less specific, meaning assistive technology may present the information in a less ideal manner.
There are a few issue with the original question's example, though:
If you wish to have the text be announced in the same as an alert is, aria-live="assertive" should be used rather than the alert role. That aria-live value is what causes the screenreader to announce the text when it does for an alert.
The text to be announced should be set on the element with the progressbar role using the aria-valuetext attribute. It should not be set solely on a separate adjacent element. If it needs to also be included in another element for presentational reasons, that element should have aria-hidden="true".
Per the spec, aria-valuemin and aria-valuemax are to be specified even when the progress is indeterminate (like a spinning loading indicator). These could be set to 0 and 100 respectively as simple placeholders implying a percentage.
When the loading is complete, the aria-valuenow could be set to whatever was used for aria-valuemax, and aria-busy can be set to false.
This leads to one potential alternative to the original question:
<div id="loading" role="progressbar" aria-valuetext="Working…" aria-busy="true"
aria-live="assertive" aria-valuemin="0" aria-valuemax="100">
<div class="mgBot15" aria-hidden="true"><span class="txt16">Working...</span></div>
<img src="loading.png" alt="" />
</div>
After a day of fiddling with a similar issue, I was able to finally get this working with a lot of reading and experimenting. I'm using NVDA for a screen reader.
<div class="loader" show.bind="isLoading" role="alert" aria-label="Loading"></div>
The following attributes were key: role and aria-label.
Above example makes NVDA announce "Loading alert" once isLoading becomes true. Important to note is that NVDA pronounces the aria-label value, followed by "alert". Using roles "log" or "status" did not end up in any announcement.
Bootstrap used role="status" like this :
<div class="spinner-grow text-primary" role="status">
<span class="sr-only">Loading...</span>
</div>
and in MDN it said :
The status role is a type of live region and a container whose content
is advisory information for the user that is not important enough to
justify an alert, and is often presented as a status bar. When the
role is added to an element, the browser will send out an accessible
status event to assistive technology products which can then notify
the user about it.
There's a good article I came across that explains what needs to be done for this scenario Loading spinner accessibility
The spinner should be included inside the container. Its visibility can be toggled in relation to the aria-busy attribute. They should always be opposites, i.e, if currently loading, section[aria-busy="true"], .tn-spinner[aria-hidden="false"], once the content is loaded, toggle to false and true respectively.

Accessibility for button with font icon in it

I'm having an accessibility problem with the button element. I'm wondering if this is the good way to do it. I have a button and the only content is a Font-Awesome (font-icon) in it. I was wondering if adding a title attribute to my button was enough to make it accessible ?
Like this:
<button class="prev" title="My accessible title">
<i class="fa fa-chevron-circle-left"></i>
</button>
The correct property in this case should be aria-label or aria-labeledby:
<button class="prev" aria-label="My accessible title">
<i class="fa fa-chevron-circle-left"></i>
</button>
With this, the screen reader for example will reproduce My accessible title instead the icon inside it.
See more:
https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques/Using_the_aria-label_attribute
https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques/Using_the_aria-labelledby_attribute
You have to use both titleand aria-label attributes as some screenreaders does not read the title attribute, while other users won't benefit of the aria-label attribute.
You have to remember that accessibility does not only target screenreaders users but also every other people, so aria-label won't be sufficient.
Also note that, for better accessibility, you might want to add a way to show the description when you focus the button with the keyboard. That would be a good idea.
That being said, I will be silly enough to suggest that some part of the description of your button might be always visible for better accessibility.
For instance, the following examples shows how the two attributes might be used conjointly with a short visible hint for a popup close button :
<button aria-label="Back to the page" title="Close popup">
<i class="fa fa-times"></i>
Close
</button>
The title attribute is the most widely supported attribute for assistive technologies. This includes Dragon (which heavily relies on the title attribute for targeting elements) as well as all modern screen readers that implement the ARIA accessible name computation algorithm and many older screen readers.
As can be seen in step D of that algorithm, the final element that is evaluated is the title attribute.

button without the form is semantic?

In html5 can I use <button> outside the <form>, like this:
<body>
<form action="page.html" method="get" id="myForm">
...
</form>
<button type="submit" form="myForm" value="Submit">Send</button>
</body>
But I do not want to use the form, only the <button>, because my project is all done with Javascript/Ajax
I wanted to make a "noscript-friendly" design, but it is a closed intranet and for a company project and do not have much time for this.
Use <button> without <form> is semantic?
<body>
<div>
<button type="button">test</button>
</div>
</body>
Or would be better to continue to use <a href="javascript:void(0)">?
Note: Remember not all valid code by W3 is a semantic code
Your use of the button element is appropriate.
That’s why there is the Button state in the first place. The HTML5 spec also shows an example, very similar to your use case:
The following button is labeled "Show hint" and pops up a dialog box when activated:
<button type=button
onclick="alert('This 15-20 minute piece was composed by George Gershwin.')">
Show hint
</button>
Note: Your question has nothing to do with the Semantic Web. There is a difference between "semantic (markup)" and "Semantic Web".
Your use of the button element is "semantic" in the sense that you are using it correctly according to the HTML5 specification, and that there is no other element defined which would be more appropriate.
You might want to use the a element in cases where you are navigating to another resource (no matter how it’s implemented technically). For apps, the difference is sometimes not very clear. A rule of thumb: if the URL changes (could users want to bookmark/share it?) and/or you could use a link type (even only theoretically), it’s likely that you should use a instead of button. But as this is a different question, please take it just as a side note.

Clicking a checkbox in a link causes the link to the followed — how can I avoid this?

I have checkbox insde a link. In all browsers except Chrome, when clicking on the checkbox you follow the link (instead of just having the checkbox become selected).
How do I avoid this behaviour?
Demo (hover over one of the product images to see the checkbox):
http://livedemo07571.prestatrend.com/category.php?id_category=9
And here’s the code in question:
<a href="http://livedemo07571.prestatrend.com/product.php?id_product=25" class="product_img_link">
<img src="http://livedemo07571.prestatrend.com/img/p/25-65-large.jpg" height="469" width="469" alt="Crew Neck Jumper" />
<span class="new">New</span>
<div class="right_block large">
<h3 class="large">Crew Neck Jumper</h3>
<span class="product_arrow"></span>
<p class="availability_container"><span class="availability">Available</span></p>
<span class="slash">/</span>
<p class="price_container"><span class="price" style="display: inline;">$2,390.00</span></p>
<p class="compare large"><input type="checkbox" class="comparator" id="comparator_item_25" value="comparator_item_25" /> <label for="comparator_item_25">Select to compare</label></p>
</div>
</a>
This isn't valid HTML (see report). The way to avoid this is, quite simply, to include only text or images inside an anchor tag, and move the checkbox outside. You could use some jQuery to add a click event to the box which would navigate to the next page.
If you want for-sure don't want to move it outside the <a> then you'd have to have an onclick="return false;" and add a listener with jQuery that toggles it when its clicked. I'm not sure if this would work in all browsers, and your best option is just to do it a standards friendly way.
I think this happen because you have the Div (block element) is inside the A (inline element) tag and by default the event will bubble up soon as you click the checkbox.
Even if HTML 5 has made the exception for the A tag and now allow a block element to be nested within that inline element. To get that working the same accross all browser you'll have to wait they all support the html 5 features
1) try with a different doctype
2) build the div outside the A has the link is not required to be executed