Specifying Screen Reader Announcements for Textboxes - html

I am posting a new question after having put a few hours into searching for a solution, and reading through Similar questions.
Using NVDA, when the textbox receives focus, the label (Organization) is read, then the aria-describedby content (200 West Street, New York, NY), and then the value (Goldman Sachs):
<label for="organization">Organization</label>
<input type="text" id="organization" value="Goldman Sachs" aria-describedby="organizationLocation" />
<span id="organizationLocation">200 West Street, New York, NY</span>
For obvious reasons, in this case, it is preferred the label to be read first (Organization), then the value (Goldman Sachs), then the aria-describedby content (200 West Street, New York, NY).
I have also attempted referencing the textbox from the aria-describedby attribute, though the value of the textbox (Goldman Sachs) is repeated, being announced once after the label (Organization) and once after organizationLocation:
<label for="organization">Organization</label>
<input type="text" id="organization" value="Goldman Sachs" aria-describedby="organization organizationLocation" />
<span id="organizationLocation">200 West Street, New York, NY</span>
How difficult is it to achieve the desired functionality?

You generally don't want to dictate how a screen reader will announce an element. Different screen readers may announce things differently. Did you test with JAWS or VoiceOver (Mac) to hear the order?
Elements can have an "accessible name" and an "accessible description" in addition to their role and their value. (See WCAG 4.1.2 and the "Accessible Name Computation"). The name and value are often announced first, and then the description, although as you noted, you are hearing the value after the description. That's just how NVDA is choosing to announce it and will be the expected order by NVDA users. If you change that order, it might confuse NVDA users.

Related

accessibility and 3 prices - old (invalid), current and promo price - for items in the shopping cart

For customers, for each item, 3 prices are displayed in the shopping cart, if promo was applied:
Example:
Jeans $99 $49 $29 Quantity 3 Total: $87.
$49 is a current price, but with applied promo it became $29.
$99 is crossed and in gray, it's the old price before it became $49.
For most of customers, it's colored, bolded and sized the way there are no questions for most of customers.
If we do nothing from the accessibility point of view, then the screen reader will read all 3 prices for one item, and it will be confusing for customers.
How to properly deal with such situations for the customers who use screen readers? Should 3 prices be pronounced (with additional words "old price" for $99, or $99 should be simply muted somehow), and what is the official recommendation in this case (if exists)?
How to modify this code to make it perfectly accessible (with an official source, if possible)?
<span class="old-price">$99</span>
<span class="regular-price">$49</span>
<span class="promo-applied-price">$29</span>
Semantically, using the <s> element indicates strikethrough so that should be the appropriate element for the old price. However, there aren't any screen readers that announce anything extra when it sees strikethrough, at least by default. You can change some screen reader settings to announce formatting changes so the user could fiddle with their settings and probably hear the strikethrough formatting, but then you'd be relying on the user have the right screen reader settings.
It'd be better to have visually hidden text that users won't see but the screen reader can still announce. This is done with CSS and a common class name to use is "sr-only" or "visibly-hidden". You can see an example of "sr-only" here - What is sr-only in Bootstrap 3?.
(Note: you don't have to use bootstrap. You can create your own CSS class and call it "sr-only" [or call it whatever you want] and copy the CSS from the stackoverflow reference.)
So your code would look like this:
<span class="old-price">
<span class="sr-only">old price </span>
$99
</span>
<span class="regular-price">
<span class="sr-only">current price </span>
$49
</span>
<span class="promo-applied-price">
<span class="sr-only">discounted price with promo </span>
$29
</span>
Note a couple things:
I added a to the end of the "sr-only" <span> because the screen reader will concatenate the spans together and without the extra space, it would announce "old price$99". The dollar sign will break up the announcement of the sentence so it'd probably be ok but it's better to force a space before the price, "old price $99", and it's better for Braille users.
Saying "current price" for the second price isn't quite accurate if the user has a promo code. You'd probably want to indicate that somehow. It should probably say "non-discounted price" or something like that. If you don't have a promo code, then I assume there wouldn't be a third price and thus "current price" would be ok.

How to properly handle inline error messages while the user is typing (ARIA)?

We have a form on our website containing fields that are validated with JavaScript as the user types (onChange event). The error messages are shown below the field inputs in red text.
We currently use the aria-describedby and aria-invalid attributes to surface the message to NVDA. The screen-reader correctly announces when the field becomes invalid, however it doesn't announce when the field becomes valid again. This was highlighted as problematic by our testing team.
We also looked into adding role="alert" to the error field, but this appears to cause "double-speak" when the field becomes invalid - it announces the error once because of the role="alert", and again because of the aria-describedby.
What is the correct/recommended way to handle this?
You're pretty close. There are essentially two things you need to do with error messages to make them accessible to everyone (WCAG 3.3.1).
announce the error message when it happens
associate the error message with the field in error
It sounds like you're handling #2 via aria-describedby and aria-invalid. If the user navigates away from the field in error then navigates back, they'll hear the field's label (hopefully you have the label associated with the field via <label for="id">) and they'll hear the message associated with it as the description of the field because of aria-describedby. They will also hear the field announced as "invalid" because of aria-invalid.
For #1 you'll want to use a live region. Using role="alert" is one way to get a live region but that causes an implicit aria-live="assertive". Assertive live regions are generally not needed unless the message is so important that the screen reader needs to stop announcing whatever it was saying to announce your message. It's generally better to use aria-live="polite".
In your case, if the error is displayed as the user is typing (for example, if you have a "create password" field and you want to check conditions off as they type [upper case, lower case, number, special char, etc]), then using aria-live="polite" will allow the user to type at their normal speed and hear the characters they're typing and when they pause for a second then your message will be announced.
If instead you use aria-live="assertive" (or role="alert"), then as the user is typing, if you display the error message, the characters that the user is typing will no longer be announced because the screen reader will stop saying the characters and will instead announce your error message. Assertive messages might clear any pending announcement the screen reader was going to say so the user might not hear any other characters they typed when the error was announced so now they won't know what they typed.
From aria-live spec:
User agents or assistive technologies MAY choose to clear queued changes when an assertive change occurs.
Anyway, with all that being said, you're code should look something like this:
<label for="myid">Enter stuff</label>
<input id="myid" aria-describedby="myerror">
<div aria-live="polite" id="myerror"></div>
As the user is typing and your onChange() runs, when you discover an error, you'll set aria-invalid to true and inject the error message text into the <div id="myerror"> element and it'll be announced.
The second part of your question is when the user fixes the field. How will the user know when the error is cleared? As the user is typing and the error is corrected, you'll set aria-invalid to false and you'll clear the <div>. Sometimes when toggling the value of an ARIA attribute, the change is announced automatically. This happens for aria-expanded and aria-checked but generally does not happen for aria-invalid (although it might be nice if it did).
So if you want to tell the user that the field is not in error anymore, you'd need a second aria-live region that is visibly hidden that is used solely for announcing the "all clear" message. When you clear the error message from your <div id="myerror">, because live regions announce the change in content, your content changed from an error message to blank text, the screen reader doesn't really have anything to announce. I suppose it could say "blank" because that's the new content but that doesn't really tell the user that it's not in error anymore.
So with a second live region, you can inject it with a "no errors found" or "errors cleared" or some message your designer deems appropriate. So the code would now be:
<label for="myid">Enter stuff</label>
<input id="myid" aria-describedby="myerror">
<div aria-live="polite" id="myerror"></div>
<div aria-live="polite" id="allclear" class="sr-only"></div>
When an error is determined to be cleared, you inject the text into the <div id="allclear"> and it'll be announced. You'll also have to update your error detection code to clear the "allclear" message when an error is found, in addition to injecting into <div id="myerror"> and setting aria-invalid.
The last part is the "sr-only" class used on the "allclear". That's not a predefined class but is a common name for a class that can visibly hide an element so that sighted users don't see the element (you don't want to physically see the "all clear" message on the screen) but screen readers still have access to the text. You can find a sample definition of "sr-only" here, What is sr-only in Bootstrap 3?
I know that looks like a lot of information but once you have it all coded, it's not that bad.
As a final side note, if your error message color is pure red, #FF0000, then that won't have sufficient contrast on a white background (4:1). You'll need a slightly darker red such as #ee0000 (4.5:1). This will satisfy WCAG 1.4.3

Tel input autofill drops international prefix

I have an input field of type "tel" with autocomplete enabled.
<input type="tel" name="phone" autocomplete="tel" />
In Safari (both iOS and macOS), when I start entering a phone number with international prefix, e.g. +49 151, and then choose from the autofill options, the international prefix is removed.
Also, when I listen to change event, the prefix is already missing in event.target.value.
Here is a quick sandbox that demonstrates the issue:
https://codesandbox.io/s/lively-lake-bunh5?file=/src/app/app.component.html
(It happens to be an Angular app, but the issue is not limited to Angular)
How can I get the full phone number in Safari?
I hope this might help.
A full telephone number, including the country code. If you need to break the phone number up into its components, you can use these values for those fields:
"tel-country-code"
The country code, such as "1" for the United States, Canada, and other areas in North America and parts of the Caribbean.
"tel-national"
The entire phone number without the country code component, including a country-internal prefix. For the phone number "1-855-555-6502", this field's value would be "855-555-6502".
link to above

Accessibility of UI Widget that is a composite of input field and button

We have UI widget that is a composite of input field and an icon. This widget is basically meant to be used as a form field to let users select a value from a huge list of values. Users can either type a value in the input field or click on the icon to launch a dialog with all the possible value list. Selecting a value in this dialog will set the value in the input field. Users can also type a partial value in the input field and tab-out in which case, the widget tries to autocomplete the value entered and if it doesn't succeed, it will launch the same dialog as user clicking on the icon.
How would I make such a widget accessible through screen readers? There doesn't seem any role or any other aria attribute which seems to be tailor made for my usecase. At the minimum, I would expect the users using screen readers to know that this widget has an helper icon from where a value can be selected.
I am reading this as an order database/form, where call takers can just select type in the customer number or fill out the 10+ fields. And if the caller doesn't know their ID or whatever, the call taker can do a search.
I recommend removing the autocomplete on tab functionality, because that wouldn't too fun for some. I'd code it like:
<p id="instr">Put instructions here</p>
<label for="user">Look Up User</label> <input id="user" aria-describedby="instr">
<input type="button" value="Populate Form">
<input type="button" value="Search">
I made an answer about modals quite some time ago, that should get you started. The listing in the dialog may not be the most fun to wade through. I'd recommend either updating this question or making a new one for that part.
Interesting and challenging.
To start with make sure icon has an alt text which explains its role - this is assuming it is an image. If not use title attribute to explain its role.
Add a title attribute to the input box and succinctly mention that user can also chose values using icon or partially type its value to autocomplete it.
If your form design allows instructions to be placed next to the form fields place a descriptive text right next to the widget.
These recommendations may not make it entirely accessible but will surelytake you close to where you want to be. I'm hoping that this widget will be used in more than one place in your project allowing user to get accustomed to it.
Last one to consider is to see if any aria role fits your widget controls in any way.

What's the "for" for in a label tag?

Just ran across a for parameter in an HTML label tag:
<label for="required-firstname"> First Name </label>
<small>*</small>
<input name="required-firstname" type="text" tabindex="2"
id="required-firstname" size="24" maxlength="40">
I'm converting this form to a PHP processed script, can I get rid of the for= parameters?
(And out of curiosity, what does it do?)
From w3schools.org:
The tag defines a label for an input element.
The label element does not render as anything special for the user. However, it provides a usability improvement for mouse users, because if the user clicks on the text within the label element, it toggles the control.
The for attribute of the tag should be equal to the id attribute of the related element to bind them together.
HTH!
adding my $.02 as an Accessibility SME - as well as usability, the LABEL also associates the input field with the correct label so persons using screen readers will know what the field is for.
The HTML label tag defines a label for a form element. They're usually used with checkboxes and radio buttons, and when the user clicks on the label it toggles the button. With a text input (and you'll have to check this to be sure) I think it only gives focus to the input when the user clicks the label.
It specifies to which element that label is bound to. In your sample code the label is there for the required-firstname input field. If the user clicks on that label, the focus will go to the bound input field. It's a usability improvement and I think you'd be better off leaving it as is. It's a good practice.
The "for" attribute is a necessary element for the accessibility of your form. Do not omit it. For someone using a screen reader (SR) to have a web page announced to them, the "for" attribute relates the control to the label. Typically a SR user will tab through a form, from one control (which is a focusable element for the SR) to the next. Without the "for" attribute, the SR user will have to change modes on the SR and probe around the form to try and determine which control matches which label, which can be time-consuming and confusing. The "for" attribute can also be useful for assistive technology relating to motor issues.
WebAIM.org has a great page explaining the accessibility ramifications of "for": http://webaim.org/techniques/forms/controls
It ties the label to a form element id. Some form elements, like checkboxes, can be activated by clicking on their label.
In some browsers when you click on a text in a for tag, you'll check the box it's associated with (i.e. the for = id) or put the focus on that box. It's an ADA thing