Highlighting content for screen readers - html

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>

Related

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.

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.

How do screen readers handle text separated by tags (not spaces)?

For stylistic reasons I have HTML markup as follows:
h1 {
font-family: 'Heebo', sans-serif;
font-weight: 900;
}
h1 span {
font-weight: 100;
color: yellow;
}
<link href="https://fonts.googleapis.com/css?family=Heebo:100,900" rel="stylesheet">
<h1>Big<span>yellow</span>bananas</h1>
This allows me to style yellow differently and because it is styled differently, I can remove the spaces between the words so that the text looks nice yet is still readable by humans. However, this got me thinking. How is such text handled by search engines and screen readers? Assuming that they treat the heading as a single string Bigyellowbananas rather than Big yellow bananas, what is the correct way to maintain the visuals but improve the accessibility?
My guess would be zero-width spaces but I am not sure about this.
Actually, it depends on the screen reader whether or not it is read as a single word.
Jaws is most certainly going to read your text as a single word, while VoiceOver will read three words, perhaps even making an exagerated pause between them.
Ideally, as a safety, you should put an actual spaces between the words, so that you make sure everything is well read everywhere.
It doesn't matter if the space is just before </span> or just after <span>. IN fact, if you remove all HTML tags, it's obvious to see where you should put spaces.
Unfortunately I'm not a CSS expert but I'm pretty sure there is a solution with a code having correct spaces. Couldn't you change your code for something like this for example?
<h1>My<span class="space"> </span><span class="big">yellow</span><span class="space"> </span></h1>
Where .space could be in fact .sr-only, reduce the width to 1px, send off-screen or any other usual CSS trick of the same kind.
ARia-label isn't a full proof solution here in my sense. It is normally used in element interactions, but in a context where you just have text with no interaction, it isn't guaranteed to always work.
Some screen readers need a role, otherwise they ignore aria-label if there isn't also a role. However, here, <h1 role="heading"> is a bad practice, you are explicitely giving the role of something implicit (this can make other troubles).
role="text" or role="presentation" are much worse, they both makes the heading be totally skipped when navigating from heading to heading or when listing all the headings of the page.
To come back to the main question, note that VoiceOver hasn't always the correct expected behavior. Consider this:
<p>This is <span style="color: blue;">blue</span>.</p>
No problem with Jaws or NVDA, but I have already seen VoiceOver explicitely saying "period" on such codes, exageratly detaching the word "blue" from the sentance.
In that case however, I don't think there is an easy way to change the HTML in order to have a correct reading everywhere.
You are correct that the lack of spaces will cause problems for screen readers and braille devices. The heading will be read as "Bigyellowbananas" and will appear as one word on a braille device.
You can fix this by using an aria-label on your heading.
<h1 aria-label="big yellow bananas">Big<span>yellow</span>bananas</h1>
The aria-label overrides the text within the heading for screen readers and braille devices.

How can I exclude HTML text nodes from the browser's search function?

Is there some ARIA or other way to mark a given HTML node so as to be skipped when the user searches for text on the page (Ctrl+F/Cmd+F)?
Use case: hiding accessible/fallback text from searches
Example: search on this page for the word down. You should only find the instance in the previous sentence, but Chrome will show as many search results as there are answers to this question, plus one, because the question itself, and each answer, have a "d... vote" a link text.
Such search results aren't highlighted, and it can appear frustrating to see "1 of X" in the search box, while there's nothing visible that matches what the user has searched for.
Not sure if I understood you correctly, but if you develop your own app, not hacking SO source, maybe using of CSS :before or :after pseudo-elements filled with content property will help.
For example, the text ”Hello“ is not found in Safari, Chrome and Firefox when added by the content property:
.text:before {
content: 'Hello';
}
Opera 12.x finds the word on the page, so if its support makes sense for you, this solution won't work. I also haven't test it in any version of IE, mobile browsers and other infrequent environments.
In the example you could remove the "down vote" text (replacing it with , whitespace, or empty string) because the a tag already contains a title attributes which aimed to be used by screen readers.
The fallback is then only necessary with a text browser like lynx, which will ignore CSS. So, you can use a markup like
<a href="#" title="Explicit alternative">
<span class="hidden">Explicit alternative</span>
</a>
Setting display:none on class hidden
If you doubt that your title attribute is enough, you could add an aria-label attribute, but it's not necessary.

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/