Uncanny A11y

The pun in the title is that some people pronounce the a11y numeronym as “alley”. That makes the full title sound like uncanny valley, the concept of human-looking things seeming almost, but not quite, human and therefore creepy.

In accessibility, the same thing can happen. Developers can try so hard to make sure something is accessible that the entire experience becomes weird, confusing, or downright unusable.

There are generally two things that contribute to this:

  1. thinking that using code, all the code, is the best way to make something accessible, and
  2. not testing with users who have disabilities.

Unfortunate Examples

These examples reflect real sites. I see them over and over. These examples also do not trigger automated accessibility checkers because they are technically doing nothing wrong.

Just tabindex Everything

Sometimes when developers first realize that screen reader users do not use a mouse (mostly), but instead rely on a keyboard, they can get a bit overzealous. These developers build a table and realize they cannot tab to individual cells on their computer. This is confirmed when testing using a screen reader. They rediscover this with lists, headings, regions, and so on.

Without knowing that screen readers have built-in controls to navigate tables (and lists and headings and regions), they believe that adding tabindex to every element guarantees keyboard access. I come in and I see the following:

<h2 tabindex="0">Do Not Do This</h2>
<table tabindex="0">
    <th tabindex="0">Author</th>
    <th tabindex="0">Title</th>
    <th tabindex="0">Year</th>
    <td tabindex="0">Emma Dorothy Eliza Nevitte Southworth</td>
    <td tabindex="0">The Hidden Hand</td>
    <td tabindex="0">1888</td>

This is compounded when using positive tabindex values. Many developers do not realize those items will come first in the tab order, before any other native controls and controls with tabindex="0". This can easily make the visual layout of the page fall out of sync with the page order. Some, however, do this intentionally.

Using aria-label As a Hint

The trick with aria-label is that it overrides the built-in accessible name on a standard control. Sometimes developers will add aria-label thinking it is a hint for screen reader users, not realizing that they have made a link useless or a button confusing.

In the following code the link will be announced only as Opens in a new window, the button as Cancel. The button may be confusing for a user who wants to close an alert but thinks he may be canceling an entire process instead.

<a href="http://example.com/" target="_blank" aria-label="Opens in a new window">Visit their site</a>
<button aria-label="Cancel">Close</button>

Following is an example from GitHub. When a screen reader user reads this content, she will hear Only those with Link Learn more about permission levels to this repository can merge pull requests.

<span class="status-meta">Only those with <a href="https://help.github.com/articles/what-are-the-different-access-permissions" class="tooltipped tooltipped-s" aria-label="Learn more about permission levels">write access</a> to this repository can merge pull requests.</span>

Some developers lean on aria-label to populate tool-tips, further confusing its true purpose.

Added 27 May 2022: The Mount Sinai web site employs the User1st overlay. When the overlay loads, through no action from the user, it overrides every link on the page (the line feed is in the User1st code):

<a href="http://giving.mountsinai.org/msorghp" target="_blank" aria-label="To make this website accessible to screen reader, press combination of alt and 1 keys.
  To stop getting this message, press the combination of alt and 2 keys.">Make a Gift</a>

Unhelpful alt Text

Too often every image on a site is preceded with “photo of” or “picture of”. Authors generally do not know that screen readers pre-pend the announcement of alt text with “Graphic”, so these users will hear “Graphic photo of a silver car.”

<img src="…" alt="Photo of a silver car.">
<img src="…" alt="Picture of a screen shot of the WIndows Mobile home screen.">

Some authors believe that every nuance of an image must be conveyed. They may write entire paragraphs to convey the contents of a photo, when all that is needed in context of the page is something as simple as “A coffee mug”. Compounding this is when authors think that alt text is re-usable everywhere without changes, when often the point of an image will change based on its use and context.

Come try our coffee!<br>
<img src="…" alt="A four ounce white porcelain mug with a square handle on a matching white saucer, both resting on a dark wood table polished to a gloss; in the mug is a mound of white foam with dark edges at the rim.">

For images used as links the alt text not only needs to be brief, but it also needs to convey the point of the link. If I am linking to a bag of coffee beans on an ecommerce site, “A coffee mug” won’t do. If I am linking to a company via its logo, then Visit our partner Enron logo sounds weird.

Visit our partner <a href="http://example.com"><img src="…" alt="Enron logo"></a>.

Some outlets have applauded the efforts of Facebook to auto-generate alternative text for images so that users (or, more imporantly, brands) would not need to. The problem is that AI cannot understand the author intent of an image. Generated text also read like a machine, eg: Graphic. Image may contain: 2 people, people smiling, eyeglasses, outdoor and closeup.

<img src="…" alt="Image may contain: 2 people, people smiling, eyeglasses, outdoor and closeup.">

Similarly, alternative text for an image in one part of a site might need to be different elsewhere on the same site.

Overriding Default Pronunciation

Sometimes a developer will start testing with a screen reader and decide that the way a screen reader pronounces words is wrong. When this happens, instead of accepting that maybe users don’t care, they may try to code around it (and the resultant screen reader pauses for hidden content). Usually it is just a hidden span, but I have seen some robust solutions:

Please enter your 
  <rt aria-hidden="true" style="font-size: 1em"><!--Standard-->licence</rt>
  <rt style="display: inline-block; width: 1px; height: 1px; overflow: hidden"><!--Phonetic-->license</rt>

It is not restricted to pronunciation. Often currencies, temperatures, time spans, dates, and so on can confuse a developer listening to it for the first time. It can be particularly taxing for users when developers make them even more verbose (and compound it by making each one a tab-stop).

<div tabindex="0" aria-label="September 16th 2016">16</div>
<div tabindex="0" aria-label="September Sixteenth Two Thousand and Sixteen">16</div>

I have also run into cases where developers truly believe every foreign word used in a sentence, including common idioms, must be wrapped in a container with a lang attribute. The frustration comes when the screen reader pauses at the container, not to mention when the word sounds different than it has every other time for the user.

I would like a <span lang="it">cappuccino</span> and a <span lang="fr">croissant</span>, and hopefully it comes in under my <span lang="li">per diem</span> for my expenses.

Punctuation can also be mis-applied, particularly in image alternative text or hint text, where authors assume every fragment is a full sentence and warrants a period.

This is the best <img src="…" alt="Pie."> I have ever had, and I do not like <img src="…" alt="Peach."> normally.

In that case, even first-time screen reader testers will probably recognize the impact of the two periods.

Added 7 July 2023. I go into more detail in my post Don’t Override Screen Reader Pronunciation.

Mis-using aria-roledescription

Every time I see aria-roledescription in the wild, it is to offer hint text. Something like this painfully real example:

<a href="[…]" […] ariaroledescription="Press enter to activate the menu.">

This developer has effectively told the screen reader that instead of announcing 200, link to replace it and say 200, Press enter to activate the menu.

There is no HTML element by that name. There is no ARIA widget by that name. It is meaningless and hides the control type. Is it a button? A menu bar? A select? A disclosure widget?

For screen readers that correctly (per spec) override the native role with what the developer provides, the user will have little understanding what the control is. The screen reader may still offer its instructions, perhaps as You are currently on a Press enter to activate the menu inside of web content. To activate this, press Control Option Space.

I have put together more reasons why you should be careful using aria-roledescription.

Providing Control Instructions

Many devs think they have to tell screen reader users how a control works, regardless of the fact that using the correct HTML and/or ARIA will allow screen readers to convey that to users.

Besides that being incredibly verbose, it can also be wrong.

<button aria-label="Click button to mark">

Never mind that this overrides the accessible name of the control, this is obviously problematic for a user who does not use a mouse, such as most screen reader users. TalkBack, for example, will tell a user to double-tap to activate when encountering a button.

<a href="[…]">
  Services<span class="visually-hidden">, tap to follow</span>

Even if you go so far as to test for a touch display and think you can offer instructions appropriate for the context, you will still be wrong. Keyboards paired with mobile phones while running screen readers is incredibly common, so telling the user to tap is contextually wrong. Never mind devices with multiple form factors.

Obviously for custom controls and complex widgets you likely need to offer some basic instructions. Otherwise a screen reader is going to take context into account and provide instructions specific to the platform. It will indicate when the custom accelerator key is needed (JAWS key, Narrator key, VoiceOver key, etc.). It will adapt to a touch screen and tell a user when a tap, swipe, or hardware control is needed. Do not pre-judge what hardware the user has available and can use.

ARIA Authoring Practices

The ARIA Authoring Practices is considered a go-to resource for pre-built accessible patterns. Essentially, a free pattern library for the taking. It is not a standard even though some treat it as one. It is only a note — a bunch of material that may be useful to some authors.

These patterns try very hard to mimic native operating system patterns. However with those efforts they generally do not identify current browser support or bugs, often do not disclose dependencies clearly, are not mobile-first (if at all), fail to note the absence of necessary JavaScript events, disagree with published W3C tutorials, and in many cases are not fully tested. There are open issues where users complain that the recommended patterns are cumbersome or confusing. These problems result in large platforms encoding confounding interface patterns.

As they are integrated into projects and usability testing is performed, the gaps are becoming more and more apparent. Teams that did not expend the effort to test them are losing their trust in W3C recommendations as a result. I say this with confidence because I am the guy standing in front of rooms of 30 developers at a time on a twice-monthly basis having these conversations.

I have written in more detail on a couple of these patterns:

Update 20 May 2022: APG Relaunches

On Global Accessibility Awareness Day (GAAD) 2022, the APG relaunched and rebranded itself as an accessible pattern library:

I am thrilled this no longer looks like a standards doc and is much easier to navigate.

I am less thrilled this left a pile of 404s with the move, implies it is a ready-to-use pattern library, obfuscates the (watered down) warnings I fought so hard to get added, quietly hid some of its worst patterns with no acknowledgment in years-old issues, appears to have happened outside the W3C redesign project with Studio24, and introduced WCAG issues.

Update 30 April 2023: APG Adds Support Charts

Despite claims, APG’s support charts are not ARIA support charts and they are not analogous to Can I Use. While brand new and likely to grow, their scope is still strictly APG patterns. I go into more detail in my post No, APG’s Support Charts Are Not ‘Can I Use’ for ARIA.

I include comparisons with Can I Use and a11ySupport. I also note that APG is still stuck on screen readers only, which means it creates gaps for other assistive technologies and allows WCAG violations.

The Marketing Term ‘AI’

Added 8 July 2023. I am going to take the large language model (LLM) popularized by ChatGPT and OpenAI. While marketed as artificial intelligence (AI), this is little more than a dynamic autocomplete designed to sound truthy.

As I have written before, No, ‘AI’ Will Not Fix Accessibility.

This does not stop companies from marketing fake-AI to solve accessibility problems (with breathless parroting by non-journalists) regardless of hilariously bad outcomes from egregiously inaccessible tools.

Here is UserWay’s output when asked for a text entry field for a numeric 6-digit 2-factor authentication page (this within a code block with aria-hidden="true"):

<label for="otp">Enter the OTP:</label>
<input type="text" id="otp" pattern="[0-9]*" inputmode="numeric" maxlength="6" aria-label="OTP" required>

Or asking for a password field with some standard requirements:

The title attribute provides a description of the password requirements for screen readers.

Or when fed this obviously nonsensical code:

<div role="button" aria-pressed="false" aria-selected="true" type="submit" aria-label="Get started" title="Get started" href="/sign-up">
  <span aria-hidden="true">Get started</span>

UserWay returned this with a false justification for every attribute:

<a role="button" aria-pressed="false" aria-selected="true" aria-label="Get started" title="Get started" href="/sign-up">
  Get started

Granted, expecting fake-AI to create better outcomes for humans is a stretch given the incredibly negative feedback MDN has received from its two efforts to have fake-AI explain even simple code blocks that themselves are not accessibility issues.

Since LLMs are trained off many of the poor practices I cite throughout this post, LLMs actively regurgitate similar bad advice.

What You Can Do

I have a couple suggestions.

Test with Users

The bulk of these issues are a function of not knowing how real users actually surf. Developers make assumptions about what will be easier for a screen reader user (or zoom user, or voice user, …) without testing it with screen reader users (or zoom users, or voice users, …).

I cannot teach you how to start testing with users if you never have before. I can, however, direct you to video and slides of my talk Inclusive Usability Testing that covers some of the logistical aspects of incorporating users into your process.

Maybe Code Less

Some developers don’t know what these elements, attributes, or features really do, so they end up keeping defaults or adding arbitrary values. Again, without testing with users or assistive technology they have little way of knowing what a mess they have created.

If developers worked to follow the three, no, five Rules of ARIA, much of this might solve itself:

  1. If you can use a native HTML element or attribute with the semantics and behavior you require already built in, instead of re-purposing an element and adding an ARIA role, state or property to make it accessible, then do so (rule 1 reference).
  2. Do not change native semantics, unless you really have to (rule 2 reference).
  3. All interactive ARIA controls must be usable with the keyboard. If you create a widget that a user can click or tap or drag or drop or slide or scroll, a user must also be able to navigate to the widget and perform an equivalent action using the keyboard (rule 3 reference).
  4. Do not use role="presentation" or aria-hidden="true" on a focusable element (rule 4 reference).
  5. All interactive elements must have an accessible name (rule 5 reference).


I will likely add more curious patterns as I find them. If you want to comment with some you have seen, note that I am focused on technically valid code that is unusable and has gotten that way as a result of someone trying to make it more usable or accessible.

Update: 3 February 2022

Eric Eggert talks about the challenges that developers make for disabled users when the developers try to make something “accessible” without any understanding of disabilities or experience with the technology in his post No Accessibility Without Disabilities. As I do, he also cites tables, terrible alternative text, and tabindex everywhere.



I’m surprised to learn that ARIA Best Practices document is not standard and probably should not be trusted. Do you have a better recommendation for accessible patterns? Thanks!

Tao Zhang; . Permalink
In response to Tao Zhang. Reply

The ARIA Authoring Practices (APG) is a note, meaning it is a supplementary document to help understand or support a standard. As with any non-standards document you should treat it as a suggestion and always test its assertions.

The APG has lots of good information on keyboard shortcuts, but you should check for open issues against GitHub. The Web Accessibility Tutorials (also by WAI) offers some simple patterns. Regardless, very complex widgets, even if coded perfectly, they may still have usability issues just due to expectations and discoverability of purpose.


Thanks for writing this, I will gladly share it because there’s tons of stuff which reflect my experiences while working with other developers in here. I do, however, want to nitpick in the tiniest, (and only the tiniest), amount. In the section headed “Unhelpful alt text”, you state: “Authors generally do not know that screen readers pre-pend the announcement of alt text with “Image”, so these users will hear “Image photo of a silver car.””. Screen readers will announce “graphic”, not “image”. I’m pointing this out for the following reason: In the admittedly narrow edge case where a developer or author really does test with a screen reader, my concern is that they will listen for the word “image” and not “graphic”. When they do not hear “image”, I think there is a possibility they will believe their code is defective instead of blaming the screen reader, since although logically screen readers carry bugs/defects just like any other software, the fact that screen readers share this trait with other software is rarely if ever considered, and so developers will chase their tails trying to accommodate every quirk of the screen reader they know about. When they learn of the others they will then chase their tails trying to accommodate the quirks of the others. I realize this may all seem very far-fetched, but I’ve seen developers chase after every screen reader quirk more times than I can count, and the result is always a convoluted mess.

In response to Amanda Rush. Reply

Amanda, the nitpick is warranted. I updated the post accordingly. I also discovered the Android announces it after the image alt text. I think I knew this already, but it just lives in that void of generalizations that come when a sighted user does alt text testing.


Brilliant article Adrian. Thanks for sharing. I am laminating the main points as I write this. :)

Leave a Comment or Response

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>