How Should Split Buttons Behave with Screen Readers? - html

I have a split button construct in our applications that is similar to the following jsbin.
http://jsbin.com/opAtiYEl/8
The first button would do a default action and the second button would give a menu (ul) with more related actions.
When i tab into the first button it reads "action button". That's fine. But when i tab into the arrow down button it reads "button".
What is the correct approach to make this work accessibly? I'm thinking aria-haspopup but that doesn't read on Voice Over.
Ideally this should be correct for VOice Over, NVDA and Jaws (latest minus 2). I'm trying to find a good baseline here or suggestion?

You are some what on the right track with aria-haspopup.
And as #Menelion ElensĂșle said your arrow button has no content.
Let's say we do something like the iTunes store and have 1 link to a category and a dropdown for sub-categories...
This is the proper markup
Movies
<button type="button" class="action-dropdown hide" aria-haspopup="true" aria-expanded="false" aria-controls="movies-menu">movies dropdown</button>
<ul id="movies-dropdown">
<li>Adventure</li>
...
</ul>
Use the class "hide" to visually hide the text. (Don't use display:none)
And when the arrow is clicked change aria-expanded to true, and remember to switch it back to false when the dropdown is hidden.

My JAWS 15 says "Unlabeled 3 button". You have to label your button. Here:
<button>Action</button>
<button class="arrow"></button>
Please note: the second button has nothing between the tags. If it's impossible to insert something in there (it would corrupt your design), then it would be appropriate to make your arrow as a plain image with an alt attribute.

Related

My screen reader is not reading content inside the div tag with role button

<div role="button" aria-label="Open" tabindex="0">
<span title="open file">go to file</span>
</div>
My screen reader is reading open button.
But I want it to read open button go to file.
How I can achieve this? Thanks in advance.
aria-label overrides all text that might be contained in child DOM nodes. See https://www.w3.org/TR/using-aria/#label-support, in particular the third last bullet point:
Don't use aria-label or aria-labelledby on a span or div unless its given a role. When aria-label or aria-labelledby are on interactive roles (such as a link or button) or an img role, they override the contents of the div or span. Other roles besides Landmarks (discussed above) are ignored.
If you literally want "open" read before the role, "button", and then have "go to file" read afterwards, you're talking about having a "description" for your element, but I suspect forcing that reading order will cause a WCAG 2.5.3 Label in Name issue, which I'll explain shortly.
But first, here's how you would get that order:
<div role="button" aria-label="Open" tabindex="0" aria-describedby="newid">
<span title="open file" id="newid">go to file</span>
</div>
Add aria-describedby to the button and reference the ID for the <span> (and add an ID to the <span>).
Most screen readers will read the label of the element first, then the role, then the description, but that's not guaranteed. You'd have to test with NVDA, JAWS, and Voiceover (on the Mac and iOS).
Now, the problem with WCAG 2.5.3 is that you now have a button that displays "go to file" as the label of the button but the name (accessible name) of the button is "open". This means that a speech interface user (such as Dragon Naturally Speaking) will have to say "click open" in order to select the button but the word "open" is not displayed anywhere on the button. All the user will see is "go to file" on the button so they're going to think they can say "click go to file". But since "go to file" is the description of the button and not the name, it won't work.
So you can do what you're originally asking for but it makes a pretty severe accessibility issue.
You might want both "open" and "go to file" in the accessible name of the button and not use a description, but that means you'll hear "open, go to file, button", which is not the order that you originally requested.
ARIA: button role
👆 This May Help

How come some people use "role" attribute instead of "type"?

I'm following along with a YouTube video & it's teaching me about buttons. The video uses the attribute role, but how come they use role instead of type?
<button type="button"></button>
<button role="button"></button>
Which one should I use and why? None of the HTML documentation I've looked up shows a role as an attribute for the button.
The role attribute describes the role of an element in programs that
can make use of it, such as screen readers or magnifiers.
The button role should be used for clickable elements that trigger a
response when activated by the user. Adding role="button" will make an
element appear as a button control to a screen reader. This role can
be used in combination with the aria-pressed attribute to create
toggle buttons.
Read more on this from https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/button_role
Since you are already using a button element. It no longer needs role="button" attribute since it is itself a button and all the events are already available.
So it is not recommended to use role="button" on button.

How to add button role to a custom element in angular to make it accessible by screen reader?

I have a custom component in angular that handles images. I have alt text as an input to the element and the screen reader picks it up to utter it out. But whenever I tab to the image, it says 'Trash' group. I want the screen reader to read it out as 'Trash' button. How can I achieve this? The following is my current implementation:
Icn component:
<img [ngClass]="class" [file]="file" [alt]="alt">
Usage:
<icn class="del-icon" [file]="'trash'" [alt]="Trash"></icn>
I tried role="button" but that didn't work.
I don't know Angular so you may need to do some digging on how to structure this but your approach is making things difficult.
Instead make the button a <button>. This way you get all the native accessibility built in (e.g. accessible via tab by default, accepts focus, has hover and focus states etc.)and you will also get the correct announcements in screen readers.
Then place the icon inside the <button> and just style it appropriately.
<button> <!--add whatever directives angular requires here-->
<img [ngClass]="class" [file]="file" [alt]="alt">
</button>
Also you may consider using inline SVGs for your icons as they offer styling options and can change colour according to user preferences. It is also one less resource to download so will help with performance.
I figured out the solution to this problem by experimenting more with the roles.
The image tag doesn't take the role="button" as an attribute. Instead, the role needs to be assigned to the parent element of the image tag i.e., in my case the component icn like follows:
<icn class="del-icon" role="button" [file]="'trash'" [alt]="Trash"></icn>
Now, the screen reader software reads out as the 'Trash button' and gives further more instructions on how to interact with the button. And also if the above doesn't work, just by encapsulating the custom component in a span tag and assigning the role="button" to the span tag works like a charm.
<span class="del-btn-container" role="button">
<icn class="del-icon" [file]="'trash'" [alt]="Trash"></icn>
</span>
Note: Button role examples

How to trigger JAWS text-to-speech on button click?

My company is doing some ADA conformance revision. I need to have the button text read when the user interacts with it. Will that happen with aria-label or .. how do you do it?
The button text should be read when the user navigates to the button. That could be done with the tab or a screen reader shortcut key such as B to go to the next button, and several other ways.
Are you saying you want the button label announced when the user navigates to it and when the user selects it? That sounds like unusual behavior but perhaps it makes sense in the context of your app.
If you want something announced when the button is selected, you can do that with aria-live. You'd have to trick the screen reader into saying it. You can have a visually hidden element such as
<div id="foo" aria-live="polite" class="sr-only"></div>
(Note: See What is sr-only in Bootstrap 3? for info on the "sr-only" class.)
When the button is selected, inject the text you want announced into the <div> and it'll be read.
A Screen Reader will announce the title of the button when it comes into tab focus, and let the user know that it's a button to begin with. As a base requirement though, a native <button> element should be used since the functionality is already built in. With that said, you don't need any other particular aria tags by default.
I'm guessing you just want to know how to mark up a button so that JAWS says its text when the user tabs or cursors to it.
If it's a native button with text written on it:
<button>Next</button>
JAWS will read it automatically.
If it's an input:button with a text value:
<input type="button" value="Next" />
again, JAWS will speak its text automatically.
If it's a button with an icon:
<button><span class="fas fa-arrowRight"></span></button>
mark it up like this and JAWS will speak its name (remember to change the aria-label text if you're using a different language):
<button aria-label="Next"><span aria-hidden="true" class="fas fa-arrowRight"></span></button>
Hope this helps.

ARIA Screen Reader - how to make a role name read?

I am trying to make my web application more accessible and one of the things I want to do it create a role group and the contents inside should be read in a particular fashion.
For ex on the UI it looks like a menu bar
TITLE
Button1 Button2 Button3
The html looks like
<div class="tab-content-header" role="menubar">
<span id="{{label}}">{{label}}</span>
<button type="button" class="btn btn-primary">button1</button>
<button type="button" class="btn btn-primary">button2</button>
</div>
I want the screen reader to focus on the button ONLY and read 'button1 button, title" and "button2 button, title". Right now it doesnt read that way. any idea?
Before I answer your question, note that you are using a role="menubar" but none of the items within contain role="menuitem". I recommend you read through the menu bar pattern in the ARIA Authoring Practices 1.1, as it also defines the keyboard actions you will need to implement. Further, in most cases using ARIA to define menus is a way of telling a user that it will behave just like a system menu bar. If you do not match the necessary interactions then you will confuse users.
Now, a screen reader will announce the accessible name of a <button> as the text within the element: <button>Accessible Name</button>
If you want it to announce some additional text, you can use aria-describedby, though it will be announced after a pause.
So this may get you what you want:
<span id="Desc">Description text</span>
<button aria-describedby="Desc">Button Text</button>
Now, you state that you want something to be read in a particular order, and that you want only the button to be read, and your question says you want a role name read. These are all confusing requirements so I am not sure I addressed your goal.
All that being said, please be careful to assert how a screen reader user should experience your content. Often using ARIA to enforce the author's ideal reading order makes a page more inaccessible than if nothing was done at all. So please be certain to test with real users.