Stop screen reader reading the href in <a> - html

I have anchor tag defined as below:
<a href="www.abc.com">
<div tabindex="0" aria-label="XXXX">
...
<div>
</a>
Currently, the screen reader reads the content of href in <a> tag. However, I don't want the href to be read, but the content in the aria-label in the div.
I would like to know what is the right way to achieve the goal?

Your <div> does not have any semantic meaning so the aria-label will essentially be ignored. See https://www.w3.org/TR/using-aria/#label-support. Specifically, the third last bullet point:
Don't use aria-label or aria-labelledby on a <span> or <div> unless its given a role.
You do not want tabindex="0" on an element that is not actionable/interactive.
Just put your aria-label on the anchor itself:
<a href="www.abc.com" aria-label="XXXX">
Note that if there is any visible text in your anchor link (you have "..." in you sample code so I wasn't sure if there was any text there), make sure the aria-label contains that same text, plus any additional text that you want. If you don't, then speech interface users may not be able to select your link.

remove aria-label from the elements or you can use aria-hidden="true"
Screen reader cannot read me
To know more about this check here

Add the attribute aria-hidden=“true” to the <a> to hide it from screen readers. That will hide its child elements as well, so add aria-hidden=“false” to the <div> to un-hide it.

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.

Can a <span> be made into a clickable link?

To make a span into a clickable link.
I have made a span that contains only a background image (as part of a Gilder/Levin image replacement technique) into a clickable link, and it seems to work fine -- but, so far, that is only on my own desktop computer, and on Chrome, Opera, and IE 11.
Is this viable?
<div id="logo">
<a href="[absolute url]">
<span></span>
</a>
<h1>page name</h1>
</div>
It works on my computer, with Chrome, IE11 and Opera. Will it work universally?
While it might look okay in most browsers, you're using the <a> element incorrectly, as what goes inside it should be a meaningful label. The proper thing to do would be to wrap the entire <h1> in the link, or to put the <a> within the <h1> (both are valid HTML5).
<a href="[absolute url]">
<span></span> <h1>page name</h1>
</a>
But judging from your comments, it's probably too early for you to start worrying about image replacement techniques an web semantics when you're still figuring the syntax out.
What's the point of image replacement techniques and why using an empty <a> tag is bad?
The Gilder/Levin image replacement technique involves adding non-semantic elements to a page (such as <span> elements) and using CSS to replace them with icons, so that these elements are ignored by screen readers. After all, an icon next to a menu button might make the button more visible for someone who can see, but the icon becomes redundant when you're blind and are using a screen reader which will read the text of the button out loud anyway. This also might make your website easier to parse by search engines.
However, in the original code, you didn't put any label on the link (actual text between the <a> and </a>), therefore making it especially confusing for screen readers and robots to know what this link is supposed to be. The entire title should be within the <a> element in this case, allowing the whole line to be clicked to follow the link. It's definitely not a good practice to use an empty <a> element, and the fact that there is a <span> within it changes nothing.
And since the idea of leaving an <a> element is semantically absurd, I haven't found any reliable place documenting the behavior of such an element across browsers.
wasn't pretty sure what you are asking for:: or trying to achieve.
3. wrap span in a href tag.
2. span onclick() function with javascript
1. span:hover with css.
<div id="logo">
<a href="[absolute url]">
<span>this span is now like link text.</span>
</a>
<h1>page name</h1>
</div>
<div id="logo">
<span onclick="myFunction()">this span is now like link text.</span>
<h1>page name</h1>
</div>
<style>
span:hover{color:red;}
span:active {color:green}
</style>
The css one isn't really click stuff.
Yes, it's a reliable way to put <span> or <img>(or any element you want to be a link) in a <a> tag.
click here for Definition and Usage
The tag defines a hyperlink, which is used to link from one page
to another.
The most important attribute of the element is the href attribute,
which indicates the link's destination.

Accessible method for image replacement with title (title and aria-label)

On my web page I have an anchor (code below), which I visually display as an image (logotype) completely hiding the text. I'd like the anchor to be:
accessible - read properly by screen readers,
display a tooltip when hovered by mouse (the tooltip explains the image logotype, which may not be understood by everyone).
I use the following method:
HTML
<a href="http://some-institution.com"
title="Some Institution"
class="replace-text-with-image">Some Institution</a>
CSS
.replace-text-with-image {
/* Hide the text. */
text-indent: 100%;
white-space: nowrap;
overflow: hidden;
/* Display the image. */
width: <image-width>;
height: <image-height>;
background-image: url(<url-to-image>);
background-size: <image-width> <image-height>;
background-repeat: none;
}
The problems with the method above:
A guy reported to me that on encountering the link his screen reader reads both the link's contents ("Some Institution") and then the link's title ("Some Institution" again), resulting in a "stutter".
I read (in this article) that using title for accessibility is wrong and aria-label should be used instead.
So I tried re-factoring to use both aria-label and title:
<a href="http://some-institution.com"
title="Some Institution"
aria-label="Some Institution"
class="replace-text-with-image">Some Institution</a>
Now NVDA (the screen reader I'm testing on) reads both title and aria-label attributes resulting in a stutter again.
Other possible solutions which won't work:
When I remove the title attribute and leave only aria-label it's read fine, but I can't remove title attribute, as that's an explanation for the visual users that I want to have.
I could also stay with just title attribute completely removing anchor's contents, but I feel having an empty anchor is not a particularly good practice, isn't it?
What's a solution for that problem?
First off, I would really encourage you to use the simplest possible markup, which would be an anchor element wrapped around an image element, like this: https://jsfiddle.net/pLuqqh8w/
You should be using the title attribute of your anchor element to describe the intent of the link (i.e. where it goes), and use the alt attribute to describe the intent of your image (i.e. what it is). This is how the technology is designed to work. The alt and title attributes should not be same thing.
That being said, if you REALLY want to have a tooltip that isn't announced by screen readers, here's how I would recommend doing it: https://jsfiddle.net/neht6v01/
EDIT: Using the title attribute isn't wrong per-se, it's just not something that should be relied upon because it has very spotty support among screen-reader/browser combinations.
You should think about which ARIA role you have to give.
The a[href] is a link. Can it be also an image? No. So, create an image.
<a href="http://some-institution.com" aria-label="Some institution">
<span class="replace-text-with-image" role="img" title="Some institution">Some institution</span>
</a>
This way, the screenreader will announce the aria-label. And the title will be available to mouse users.
title is not bad for accessibility but can be useless for screenreaders. So you should not rely only on the title attribute but, as you perfectly pointed out, aria-label is useless for non-screenreader users.

Having trouble with setting a div to be readable by a screenreader

Problem: I have a div that is nested inside a span tag with the role of button, whenever the span button is focused, what I want to have happen is the screen reader 'read' the text in the nested div --> p tag when the span receives focus
<span role="button" tabindex = 0>
<div id= "nestedDiv" aria-hidden ="false" tabindex = 0>
<p tabindex =0> Read this text </p>
</div>
</span>
I tried different screenreaders and different browsers, same issue, it doesn't read the div, it just skips over to the next readable element.
I tried this in NVDA + firefox and it reads "read this text. button" when I tab to the span. Which browser are you having trouble in?
You could try adding an ID to the paragraph such as <p id="foo"> and add aria-labelledby="foo" to the <span>.
However:
Karl Brown's comment is 100% accurate - it's best to use semantic markup. Does the span do something? If so, it should be a button. Does it bring you to a different page? If so, it should be an anchor.
Also, why so much tabindex? It takes three tabs to get outside of this element, which is not good. If you use proper semantics you wont need tabindex and you wont need any aria attributes.

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.