The following was written due to a question Vikas Parashar asked on Twitter, that Heydon Pickering had already answered by the time I got around to checking Twitter. This post dives deeper into Heydon’s answer and calls out some more specifics about how an anchor may be exposed to assistive technologies, such as screen readers.
The anchor element (
<a>) without an
href attribute is meant to represent a placeholder link, as noted in the HTML Living Standard:
aelement has no
hrefattribute, then the element represents a placeholder for where a link might otherwise have been placed...
A potential use case for a placeholder link is in a situation where one might need to “disable” a link in a navigation. Since the
disabled attribute, and
aria-disabled are not meant to be used on
<a> elements, removing the
href would be a way to make people aware that a link would be there, pending some sort of requirement be met (see Steve Faulkner’s short note on
<nav> <ul> <!-- ... --> <li><a href="...">Our products</a></li> <li><a>Members only</a></li> <!-- gotta sign up! --> <!-- ... --> </ul> </nav>
The accessibility of a placeholder link
When using a placeholder link, one should be aware of how browsers may expose, or how assistive technologies such as screen readers may interpret the element.
For instance, without an
href attribute browsers will not allow keyboard focus to navigate to a placeholder link. This is OK, since the anchor should have no function without an
That said, sometimes developers will leave an
href off from an
<a> and add an
onclick event to it. However, if one is doing something this a larger question of “what is this element really meant to represent?” should be asked.
If the element is trying to behave like a button, use a
<button> element! Or add a
role="button" and make sure Enter and Space keys can be used to activate it. If the
onclick causes a URL/route change, then it’s acting like a link and you should really look into how to do that using the
href in your framework of choice.
Putting all of that aside for now, the following is a quick rundown of how screen readers will interpret placeholder links, with particular attention paid to if attributes that would provide accessible names or descriptions are set to the
VoiceOver on macOS 10.14.5
VoiceOver and Safari (12.1.1) will not announce a placeholder link as a “link”, but will announce it as “clickable” even if there is no
tabindex attributes on the element.
If given an accessible name via:
<a title="example">my anchor</a> <!-- or --> <a aria-label="example">my anchor</a> <!-- or --> <a aria-labelledby="id_ref">my anchor</a>
The placeholder link will be announced as if it were a
role="group" with an accessible name. VoiceOver could then navigate into the “group” to hear the announcement of the anchor’s visible text, again also announced as “clickable”.
If paired with Chrome (75), no “clickable” announcement will accompany the announcement of the anchor’s text. Similar “group” announcements will be made if the anchor is given an accessible name. But where Chrome and Safari behavior differ is that if the
<a> is given an
onClick attribute, it will be re-exposed as a “link”.
JAWS 2019 (June release) with different browser pairings
Testing with IE11, Edge (77 Chromium), Chrome (75) and Firefox (68); navigating with the virtual cursor (up and down arrows) JAWS will often only announce the placeholder links as static text. When given an
onclick attribute JAWS announce these anchors as links.
JAWS paired with Chrome or Edge, if an attribute that would otherwise provide an accessible name or description (e.g.
aria-describedby) were set to a placeholder link, then the element would be announced as “clickable” even though there’s no functionality provided.
NVDA 2019.1 with different browser pairings
Testing with Edge (Chromium), Chrome and Firefox; NVDA will announce a placeholder link as a “link” if given an
When paired with IE11, NVDA will announce “clickable” if a placeholder link has an
Similar to JAWS, NVDA paired with Chrome or Chromium Edge will announce placeholder links as “clickable” if the
<a> element has attributes that would provide an accessible name or description.
VoiceOver on iOS 12.3.1
Beyond announcing its visible text, there are no additional announcements made by VoiceOver when navigating to placeholder links.
TalkBack 7.3 with different browser pairings on Android 8.1
TalkBack and Firefox (68) will continue to announce any
<a> without an
href as a “link”. Firefox Android bug filed.
TalkBack and Chrome (75) will only announce placeholder links with an
onclick attribute as “links”.
If one is using a basic placeholder link per its intended use of representing where a link might have been placed, e.g.
<a>not a link right now</a>, then it will largely announce as intended, as static text.
It’s when the element has been provided additional attributes to provide modified accessible names, or to provide accessible descriptions, that using a placeholder link may not convey the information or (lack of) functionality expected. So, in the event where a link should have an
aria-label were it to be fully functional, that attribute should be removed, along with the
href if currently representing a placeholder link.
Finally, if adding an
onclick event to a placeholder link one should stop and think about why. If it’s meant to be a link, it should have an
href. If it’s meant to act like a button, then use a
FYI: you can check out a test page of placeholder links, here.