Force screen reader to read acronym by his full name - html

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.

Related

Should ARIA buttons provide context?

(This question is similar to Should ARIA labels provide context?, but not identical, as I'm talking about buttons and do not have full control over the markup.)
I have some amount of items and buttons that act on those items. Here's a simplified example:
<ul>
<li><span>Item: foo</span> <button>remove</button></li>
<li><span>Item: bar</span> <button>remove</button></li>
<li><span>Item: baz</span> <button>remove</button></li>
</ul>
As far as I understand, when someone using a screen reader tabs through the page, they will be read the button text but not the item text. This doesn't seem ideal to me, as they don't have context on which item the button will remove.
Assume that I don't have full control of the markup; I can only add attributes.
What is the best practice in this situation?
add an aria-label to the button that gives more context:
<button aria-label="Remove item foo">remove</button>
make the item text itself tabbable and give it an aria-label so it's read aloud:
<span tabindex="0" aria-label="Item foo">Item: foo</span>
leave things as they are, because this is intended behavior and/or I'm misunderstanding something about screen readers
something else entirely?
The answer depends on if you're trying to conform to the Web Content Accessibility Guidelines and are only worried about compliance issues (from a legal perspective), or if you want to have a great user experience regardless of whether you conform or not.
The first part, conformance, is a little tricky. Regarding context, 2.4.4 Link Purpose (In Context) comes into play but only for links. The guideline says the text for a link is ok if the user can figure out the meaning of the link from the link text and the surrounding context (such as what text is before or after it). And then context is defined as the link being in the same list item (<li>) as the surrounding text.
So that sort of fits your scenario, but you have buttons instead of links, so WCAG 2.4.4 doesn't really apply to you.
There isn't a clear guideline for the context of buttons except WCAG 2.4.6 Headings and Labels. It says that the label [of a button] must describe the purpose of the button. So who decides whether the label is descriptive enough? That's a tough call. Is "remove" descriptive enough? Maybe, maybe not. It kind of depends who you ask.
So if you are focusing on a great user experience rather than conformance to WCAG, adding context to the buttons is a really good thing.
You are correct that if a screen reader user tabs through the interface, they will only hear the button label and not the list context. But screen reader users have many ways to navigate a webpage. One option is to navigate by list elements (<ul> or <ol>) by using the L key (JAWS and NVDA). Another is to navigate by list item (<li>) by using the I key. (That's the letter 'i', not a number 1). So a user can navigate to your list items, hear the text of the list and the text of the button and get some context.
I would not recommend your second idea of adding tabindex to the list. You don't want the user to tab to elements that are not interactive.
Adding more context via a label is the best approach. I would recommend using aria-labelledby before resorting to aria-label. If you have an element in the DOM already that has the text context you need, give that element an ID and then refer to that ID in the aria-labelledby of the button. It's a little more work but then you don't have to worry if you change the text in the list because the button is using an indirect reference and will automatically pick up the new text.
You'll also need an ID on the button and then you have the button point to itself and to the context. That sounds confusing but here's all it is:
<ul>
<li>
<span id='item1'>Item: foo</span>
<button id="button1" aria-labelledby="button1 item1">remove</button>
</li>
<li>
<span id='item2'>Item: bar</span>
<button id="button2" aria-labelledby="button2 item2">remove</button>
</li>
</ul>
A simpler approach is to use aria-label as in your first suggestion but I don't like repeating text in an aria-label that's already in the DOM. If your list text changes at some point, you have to remember to change the aria-label too.
Making the span focusable is a very bad idea unless it produces an action itself when clicked. Only elements that are actually interactive should be focusable.
It's very confusing for the user is something is focusable but don't provide any interaction when focused.
Adding context with aria-label is a good idea, but in fact there is better.
The recommended way is to add off-screen text instead:
<button>Remove <span class="sr_only">Item 123</span></button>
Where .sr_only is a CSS class present in many frameworks with different names (sr_only, visually-hidden, etc.) which send the text off-screen. It is invisible for normal users, but read as normal by screen readers.

Highlighting content for screen readers

I have a question about highlighting search terms that match in a large document of text. So a user does a search and the matching terms are highlighted with a background color. This is fine for visual users but for visually impaired users/screen readers this is of no use.
Here is an example of what the current code looks like:
<span class="match">This is a match</span>
And the CSS is:
.match {background-color:yellow;}
So the question is ... how would you get the screen reader to announce or mark these terms as matching for the user of a screen reader.
IF you want to attract attention to a particular match, the simplest is to select and focus it.
Screen readers follows the focus, so in general the browse cursor should jump to the corresponding place. It doesn't work all the time though, especially if you do it at page load.
<span id="match" tabindex="-1">Match</span>
document.getElementById('match').focus();
Don't hesitate to extend the element focused beyond the strict string matched, so that the user can have some context. For example, focus the entire senteance where the word is matched rather than just the word alone.
You may also create an aria-live region:
<span aria-live="polite">match</span>
But it looks a priori less relevant here, since you aren't going to modify the text matched afterwards. Aria-live regions aren't always working reliably at page load.
Note that you might want to use the HTML5 element <mark> to indicate the matches, which is better semantically speaking, and looks perfectly appropriate here.
You can use ::selection pseudo-class for that.
Heres the snippet:
.match{
background-color:red;
}
.match::selection{
background-color:orange;
}
<span class="match">This is a match</span>

Alternative text for <span> element styled as icon to meet accessibility guidelines

I've been asked to look for areas of our site which do not meet accessibility guidelines. I'm currently looking into whether all icons we use that have semantic meaning have alternative text, in order to meet WCAG 2.1 1.1.1.
In one place we use a <span> element to represent a Low, Medium or High status. This is styled as an icon - just a coloured background and surrounding box with the letter L in the centre. HTML is
<span class="icon" title="Low" role="img">L</span>
Given the title and the inner text "L", is this sufficient to meet the guideline? If not, what should be added?
Rather than thinking about meeting guidelines (I can't think of a specific one you would "fail" though just so you are aware) just think what makes the site easier to use / provides the best possible experience.
As we can't see the surrounding items we can't comment on whether an "L" makes sense in context.
As such the simplest thing would be to add an aria-label to the span. This will mean that a screen reader will actually read "low" rather than "l".
<span class="icon" title="Low" role="img" aria-label="low">L</span>
You may also want to say what item is "low" as part of the label if this span isn't part of a paragraph. aria-label="widget one stock is low".
As title is not very reliable for screen readers (and useless for people on touch devices) you might also consider having a key for sighted users that explains what L, M, H etc. mean (or whatever letters you use) and then you can do away with the title.
This will also greatly benefit mobile users (if the site is mobile friendly) who can't see the title attribute.
One adjustment
I realised after the answer was accepted I didn't cover the role="image" part.
That is probably not needed at all once you have the aria-label on it, especially if you use the longer form of the label aria-label="widget one stock is low" I suggested.
Yet again depends on your use case but I would be 80% confident in saying this is the case without seeing anything else.
This will also probably help when running automated accessibility tests as it won't complain about a missing alt attribute.
So
<span class="icon" aria-label="widget one stock is low">L</span> would be perfectly valid.

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>

What is the appropriate way to hide icons from screen readers

In my web application, I have made myself a font that consists solely of icons. I use these icons to complement titles and sub titles within the application and make it more visually appealing.
However, screen readers like JAWS read this out and it makes for an unpleasant experience for users of screen readers.
For instance the character c displays an image of a cloud. I use it in this way to complement for instance a header such as <h1>:
<span class="my-font">c</span>
Now I would like for screen readers to completely ignore this as this is just complementing an existing title and not adding any new meaning to what's on the page. Through my research I have found two possibilities:
aria-hidden="true" or role="presentation"
I'm just not sure which one of these (or perhaps both) are suitable to what I am trying to achieve.
You should use the aria-hidden="true" attribute, which says:
Indicates that the element and all of its descendants are not visible or perceivable to any user as implemented by the author.
This means that the element is not supposed to be perceived by any user. So use:
<span class="my-font" aria-hidden="true">c</span>
If the icon is supposed to be a link or is not just for decoration, I suggest you have some text accompanying them so that screen readers knows what it is. You can move the text off screen so that it is only visible to screen readers.
HTML
<span>
<span class="my-font" aria-hidden="true">c</span>
<span class="screen-reader">About me</span>
</span>
CSS
.screen-reader {
position:absolute;
top:-9999px;
left:-9999px;
}
If it's just a decorative icon, it should better be served with CSS instead of HTML, for example with a pseudo-element: ::after(content:…; font:…;). Unfortunately, some screenreaders might read this content, too, and we can't apply WAI-ARIA in CSS, of course. So, depending on your situation, you might be "forced" to use markup with aria-hidden="true" instead.
If possible, you should also use a corresponding Unicode symbol (like ☁, which is "U+2601 CLOUD") instead of a irrelevant character (like c).
If there is no corresponding character, you should make use of Unicode's Private Use Areas, which are code points that are left undefined, so you can define your own characters/symbols.
You might be interested in these posts:
css-tricks.com: HTML for Icon Font Usage
nimbupani.com: Markup-free icon fonts using unicode-range
While aria-hidden="true" works to hide the audible icon, it will still show up in the assistive technology's list of links and headings.
I'm still trying to find a way to hide them entirely, but it's tricky. To the OP, yes, aria-hidden="true" will hide them somewhat, but not entirely. Don't rely on it alone. Also, make sure you test with real users!
I came across this really good article: http://pictos.cc/articles/using-icon-fonts/