Change html element accessibility text - html

On a webpage I have a div
<div class="expand">+</div>
Tapping this div expands content.
I need to change what screen readers say when they encounter this element. I've been able to come close with:
<div class="expand" role="button" title="Tap to expand">+</div>
If you tap the button, the iPhone will say
Plus ... Button ... Tap to expand
Ideally it would just say "Button ... Tap to expand," or I could have complete control over what is said.
Additionally, tapping changes the content and the title to "Tap to hide." The element is focused immediatley and the new content is read, but for some reason the title is not included this time:
Hyphen ... Button
If you tap it again it will say the title.
Is there any way to control what is said by the screen reader when you tap an element? If not, is there any specific rule that prevents the title from being read in the second case?

Suggestions from http://alxgbsn.co.uk/2011/06/06/making-web-content-more-accessible-with-ios-voiceover/ made this possible.
<div class="hide" id="tap-show">tap to expand</div>
<div class="hide" id="tap-hide">tap to hide</div>
<!-- repeat -->
<div class="expand" role="button" aria-labelledby="tap-show"></div>
You can use JavaScript to change aria-labelledby, which works.
It is important to note that the role=button is necessary and the <div> must be empty. It can contain at most whitespace. You can use a background image, or:
.expand:after { content: "+"; }

In general you should be very careful about controlling this text exactly. People using screen readers use many apps / sites, and get used to how things are read out. In the case of button text, VoiceOver will generally announce:
[Content of button]... Button... [title of button]
If this is specific to iOS then I think your initial example is good, as VoiceOver considers the title to be 'help text', which is why it's read last. Assuming you have quite a few of these, then brevity is good.
Hyphen doesn't mean much, but you could use − to get it to announce "minus", and update the title to "Tap to hide".
Something you might consider including as hidden text is what it is that will be shown. Perhaps in your interface it is obvious visually and from a screen reader point of view, but in general it would be useful to know what is going to be shown.
You could hide some text, for example:
<div ...>+<span class="hidden"> description of the content</div>
Then move the .hidden off-screen with CSS.

Related

Android Talkback reads text visually positioned above input aloud

I am trying to optimize a few components for screen readers, however Android Talkback proves to be a challenge....
Here is a very simplified example for the code:
<div class="wrapper">
<form>
<span role="presentation" aria-hidden="true">
This should not be read by Talkback
</span>
<input aria-label="This should be read by Talkback" />
</form>
</div>
The text inside the span is updated dynamically, and is positioned absolutely over the input - just to appear like an animated placeholder, without actually being read by screen readers. That is what the aria-label is for. However, TalkBack still seems to recognize the span - so it reads the content of the aria-label first, then continues reading the text in the span... role "presentation" or role "none" did not prevent this, neither did moving the text even further from the input. (For example, outside the form). Is there any way to prevent this?
The role attribute only changes the type of element that Talkback and other screen readers announce. Setting it to presentation or none just removes the semantic type of element. A <span> does not have a native role by default so it's essentially presentation/none implicitly and won't have any effect.
aria-hidden is the key. It will hide the element from the screen reader. (CSS display:none and visibility:hidden will also hide an element from the screen reader but it also makes the element invisible to sighted users too.)
Your code example should work just fine with Talkback. However, you mentioned that you dynamically change the contents of the <span>. That's not a problem but is there a chance that when you updated the text, the aria-hidden got removed?
I have used aria-hidden on Android without any trouble.
The solution in my example was already enough to fix the issue.
aria-hidden prevents the span being focusable, and if the span is located before (and not after), TalkBack will not interpret the text as being part of the input.

Force screen reader to read acronym by his full name

How can I force a screen reader to read M as Monday? (using https://www.nvaccess.org) I would like to have it more WCAG friendly
Problems:
div don't support aria-label (https://www.tpgi.com/short-note-on-aria-label-aria-labelledby-and-aria-describedby/)
M isn't clickable (so I shouldn't use button etc.)
no space for full name (Monday)
code and visual:
<section>
<div aria-label="Monday">M</div>
<div aria-label="Tuesday">T</div>
..
</section>
The wording of your question suggests using <abbr>.
You may use it, but in this case you cannot force screen readers to always read the full expanded text instead of the abbreviation.
Screen readers generally provide options whether to expand abbreviations all the time automatically, only on demand, depending on context, or never.
This is something under control of the user, who can choose what is the best for him/her. You shouldn't dictate it at his/her place.
However, looking at your particular case, you are in fact probably not looking for abbreviation and <abbr>.
As you have well identified, you are more looking for a kind of label that has to be read full text all the time.
As you have well identified too, you can't use aria-label, since aria-label is reserved for interactive elements, what your element is precisely not.
IN that kind of circunstances when you need a kind of label outside of interactive elements, a good solution is to use visually hidden text, like this:
<div>
<span aria-hidden="true">M</span>
<span class="sr_only">Monday</span>
</div>
Where sr_only is a CSS class which puts the text off screen.
You can find the CSS code of .sr_only in bootstrap. Many other frameworks have similar visually hidden text CSS classes with other names.

Accessibility: sr-only or aria-label

From MDN:
In the example below, a button is styled to look like a typical "close" button, with an X in the middle. Since there is nothing indicating that the purpose of the button is to close the dialog, the aria-label attribute is used to provide the label to any assistive technologies.
<button aria-label="Close" onclick="myDialog.close()">X</button>
According to the Bootstrap Documentation:
Hide an element to all devices except screen readers with .sr-only
So I guess I could also write:
<button onclick="myDialog.close()"><span class="sr-only">Close</span>X</button>
In a Bootstrap project, how can I choose which one to prefer?
In the MDN example, a screen reader will just speak just the word "close" since aria-label overrides the text in the button. This will work even if you re-use the code without Bootstrap.
In your example, a screen reader will speak "close x" since you are doing nothing to hide the "x" from screen readers. You are also adding a text node to then hiding it with a class.
I would use the example from MDN.
The class sr-only class is for whole blocks of text content which are only useful to those using a screen reader and should be hidden from others.
An example from and app I'm working on provides instructions for using an accessible controller with the web app:
<div class="sr-only">
When voting with the text-to-speech audio, use the accessible
controller to navigate your ballot. To navigate through the
contests, use the left and right buttons. To navigate through
contest choices, use the up and down buttons. To select or
unselect a contest choice as your vote, use the select button.
</div>
In your example, you simply want to provide different text content for a screen reader. To answer your specific question, use the MDN example.
I've use aria-labels to hint to a screen reader when to add pauses by suffixing titles with periods or commas as necessary (More about Pausing in a screen reader for accessibility):
<h1 aria-label="Hello World.">
Hello World
</h1>

Correct way to mark HTML text as decorative with ARIA

In an earlier version of the http://getbootstrap.com/components/#pagination page/section, it had the code:
<nav>
<ul class="pager">
<li class="previous"><span role="presentation">←</span> Older</li>
...
</ul>
</nav>
This has been changed to:
<nav>
<ul class="pager">
<li class="previous"><span aria-hidden="true">←</span> Older</li>
...
</ul>
</nav>
The left arrow (←) is purely decorative, and doesn't need to be announced by a screen reader. According to http://www.w3.org/TR/wai-aria/roles#presentation:
presentation (role)
Example use cases:
An element whose content is completely presentational (like a spacer image, decorative graphic, or clearing element);
An image that is in a container with the img role and where the full text alternative is available and is marked up with aria-labelledby and (if needed) aria-describedby;
...
Whereas:
aria-hidden (state)
Indicates that the element and all of its descendants are not visible
or perceivable to any user as implemented by the author.
I understand that 'role=presentation' is really talking about the semantic meaning of the element, but it seems like the left arrow is directly analogous to 'a spacer image, decorative graphic, or clearing element', and is certainly 'visible or perceivable to any user'.
What's the correct design pattern here? Is the meaning of 'aria-hidden' changing to allow for this specific limitation of 'role=presentation'?
The role attribute is used to override the default mapping of the role of the HTML element to the accessibility tree. This has no effect on the text content of the element.
For example, role="button" on a div will allow the div to be announced as a button but will not change the fact that the text of the div (e.g. "Submit") will still be announced as the accessible name.
In ARIA 1.1 the presentation role has been given a synonym of "none" to better represent its semantic http://www.w3.org/TR/wai-aria-1.1/#none
The attribute aria-hidden is used to hide the element itself and the content (accessible name) of the element from the accessibility tree while keeping it visible in the document. This semantic has always been the case. It has not changed.
unobf is correct but sometimes it helps if you think of what the screen reader user will experience. Consider this simple example:
<div role='button' tabindex=0>alpha</div>
<br>
<div role='presentation' tabindex=0>beta</div>
<br>
<div role='button' tabindex=0>gamma</div>
<br>
<div role='button' tabindex=0 aria-hidden='true'>delta</div>
<br>
<div role='button' tabindex=0>epsilon</div>
If you're using VoiceOver or the virtual PC cursor in JAWS, both will allow you to put your focus on the role='presentation' item and will not state a role but it will say 'beta'. (I like the new role='none' that unobf points out in the 1.1 spec. It makes it clearer that the screen reader should not state any role when it's set to 'none'. As the spec says, it was a little confusing using 'presentation'.) So the presentation item isn't really hidden to the screen reader. You're just telling the screen reader that it doesn't have a role.
Aria-hidden, on the other hand, completely removes it from the screen reader, except in my poor example (which is intentional). If you're using VoiceOver or the virtual PC cursor in JAWS, both will skip the aria-hidden button. The screen reader user won't know it's there. But if the JAWS user is TABBING through the page, they will land on the aria-hidden button because it's a tab stop. But since it's aria-hidden, JAWS gets a little confused on what to say. When I tried it (FF 38 and JAWS 16), it said 'beta', which is the text from a previous <div>. In general, you don't want to aria hide something but make it keyboard accessible. That's just a weird scenario.
Going back to bootstrap's old example, since they used role='presentation' and it's a <span> tag, the VoiceOver and virtual PC cursor JAWS user will both be able to put their focus on the <span> element, which is probably not what they intended. Since the arrow is just for decoration, it makes sense to aria hide it.

Is there a way to write content that screen readers will ignore?

I've just been working on a page which needs to be accessible to both sighted and visually impaired users. Some elements of the content, just by the nature of relating only to visual elements, simply do not apply to people using screen readers. For example, a link opens an audio-visual presentation in a new window, but due to circumstances beyond my control, the window is awkwardly resized, so there's a message saying that you should resize the window so you can see everything better. Obviously this is useless information to someone who can't see it anyway.
Is there an accepted way to make screen readers ignore some content?
Actually the correct way of doing this is by using the ARIA role=hidden.
Like this:
<button type="button">
<span aria-hidden="true" class="icon">></span>
<span class="hide">Go!</span>
</button>
By doing this you hide the > character so screen-readers won't read "right angle bracket", and instead read "Go!". Sighted users will only see > if you hide the content in the .hide class visually.
Like this:
.hide{
position: absolute;
left:-999em;
}
The ARIA role presentation is for "normalizing" semantic meaning, like for example a <table> with role="presentation" won't be read as table content and will be just plain text.
If you want an image not to be read you can put in empty alt text like this:
<img src="decorative-flower.jpg" alt=""/>
..or if it's an <svg> omit the <title> and <description>
<svg>
<!-- <title>Remove this line</title> -->
<!-- <description> Remove this too..</description> -->
</svg>
I have noticed in some rare situations some screen-readers have still read the empty alt images, so you could use aria-hidden="true" here as well.
CSS' speak property is not supported at this point, and the same goes for the link attribute media="aural".
Halfway through writing the question I remembered where to look.
CSS can do this:
<span class="dontRead">Screen readers shouldn't read this</span>
.dontRead {
speak: none;
}
check for this
<h1 role="presentation" tabindex="-1">Some text that screen readers will ignore </h1>
because of role="presentation" and tabindex="-1" screen reader will ignore above tag.
i checked this on ie8 and firefox 3.5 it is working with JAWS screen reader.
CSS has those aural properties, but as they aren't implemented anywhere they are completely useless.
The issue with hiding specific pieces of information from users of assistive technologies is that it assumes they are using your software alone in some dark room, which simply not a safe assumption. Many users of assistive technology collaborate closely with other users (to whom this information would be relevant), and a few very fortunate ones even have assistants. You would be wise to de-emphasize or under-prioritize this content for them instead by placing it later in the document somehow.