JavaScript Accessibility 101

Share this article

There was a time when JavaScript Accessibility simply meant ensuring graceful degradation when JavaScript was unavailable. But, since the explosion of Ajax and Rich Internet Applications, JavaScript isn’t just used for non-essential usability enhancements. JavaScript is now the core of web-based applications, so when we talk about JavaScript accessibility today, we mean that the JavaScript itself is accessible.

Future Echoes

One of the most significant developments in web accessibility over the last few years, is the Web Accessibility Initiative’s Accessible Rich Internet Applications (WAI ARIA), which defines semantics for making interactive content accessible to assistive technologies, such as screenreaders. Because the Web 2.0 explosion happened with almost no regard for accessibility, the WAI ARIA arose out of necessity. JavaScript is now used in mission-critical code, and therefore assistive technologies must be able to interpret dynamic content.

Back to Earth

Unfortunately, ARIA is not well supported yet. Only the latest versions of (very expensive) screenreaders have any support, and none of them support everything. Additionally, the bits that are supported, aren’t necessarily implemented properly.

When ARIA becomes widely supported, it will not be a magic bullet. For starters, there’s more to JavaScript accessibility than ARIA defines. ARIA can only build on a solid foundation of understanding users’ needs coupled with standards-based development.

JSPro will be devoting several articles to exploring accessible JavaScript. We’ll begin with a tour of simple things you can do right now to make your JavaScript more accessible. Later, we’ll delve more deeply into the world of ARIA. But before any of that, we to cover some theoretical ground.

Identity Within

JavaScript accessibility can be split into three broad groups of user needs. This section describes these groups in more detail.

Users of Assistive Technologies

The first group includes people using screenreaders, braille readers, or similar assistive technologies. The blind are chief among this group, but it also includes people with low vision and cognitive disabilities, who use screenreaders to aid reading and comprehension.

Assistive technologies represent all information as structured text. Therefore, all JavaScript functionality must take a form that can be interpreted as text. For example, a scripted progress meter shown below provides visual information, so this would need to be supplemented with text that provides the same information.

A progress-meter at 76%, which is indicated visually and also with a percentage figure.

A progress-meter at 76%, which is indicated visually and also with a percentage figure.

Text alone is not enough, if it doesn’t have structure and relationships that assistive technologies can understand programatically. Text is usually structured in very simple ways such as lists and tables. These are structures that assistive technologies can easily understand. All we need to do is use them properly.

By building things like dropdown menus using unordered lists and structural labels, assistive technologies can derive their meaning from the semantics and hierarchy of those elements. Or, we can build calendar widgets where each month’s view is a table. We can then trigger it with a button and describe it with a label. Solid element semantics should be the basis of all interactive content.

Keyboard Users

The second group is people who only use the keyboard. This group of users includes people who are blind and use a screenreader, but also includes sighted people who can’t use the mouse because of a motor disability, as well as people with a cognitive disability who find that tracking focus helps them to concentrate. To accommodate this group, all JavaScript functionality must be accessible to the keyboard. For example, interactions should be confined to the most intuitive keystrokes, such as Tab, Arrow Keys, Enter, and Escape.

Keyboard support often comes for free, if you follow the premise that the best event is the most device independent. So, form validation should be tied to the form’s modeless submit event, while primary activation events should be bound to the universal click event, rather than mode-specific events like mousedown, touchstart or keydown.

For more complex interactions, a combination of events is often required. The Web Content Accessibility Guidelines talk about event pairings – pairing mouse events with their nearest keyboard equivalent. An example pairing would be the mousedown and keydown events. However, this is the wrong way of looking at it, because it focuses on the mechanics of an activity rather than the purpose. It shouldn’t matter if the keyboard way of doing something is completely different, as long as it achieves the same purpose.

For something like drag and drop, there is no keyboard equivalent to the mousemove event, but we can still make it accessible to the keyboard. What we refer to as drag and drop is actually two different kinds of interaction. The first is where elements can be moved up and down to sort them, and this could be implemented using simple Up-Arrow and Down-Arrow keystrokes. The second is grab and move actions like dragging files between folders, and this could be done with something like Space to select an element, then Tab to select the drop-target, then Enter to drop it.

When non-obvious keystrokes are used, there should be accompanying text to explain them. And, in truth, some keyboard interactions will inevitably be more convoluted than their equivalent mouse interactions. But that doesn’t necessarily matter, as long as it does the same job. Accessibility is about equivalence, not equality.

Another important consideration with keyboard accessibility is maintaining a logical content-order. For example, when rich tooltips are used, they must be inserted directly after the element that triggered them, so you can Tab to them straight away and so that screenreaders read them next.

Users Who are Sensitive to Flashing Content or Time Limits

The final group is people who are sensitive to flashing or blinking content, or who can’t respond to real-time events in the expected way. As far as flashing content is concerned, this affects people with photosensitive epilepsy for whom a seizure can be triggered by such effects, as well as people who have a cognitive disability and find it more difficult to concentrate when things are moving in their peripheral vision. Limits on flashing content are defined quite specifically by the WCAG, and summarized as the Three Flashes or Below Threshold.

Time limits can also be problematic because it takes much longer to hear content spoken aloud than it does to read it. Navigating with the keyboard also takes longer than using a mouse. Therefore, time-based activity in JavaScript should be user-controllable. Limits on time-based activity are not very specific, because there are several different use cases to consider.

The general principle for time limits is that whenever an activity has to be completed within a certain time, the user is warned when the time limit is about to expire and provided with a way to extend it. For example, an online banking interface might have strict time limits on session inactivity, but user control could be provided with a simple confirm dialog (just as you see on ATMs when they ask if you need more time).

When content is animated, the animation shouldn’t last more than five seconds, unless there’s a way for the user to control it. An animation might be a purely decorative effect, and so the time restriction is helpful for people who have a cognitive disability, for whom constant peripheral animation can make it harder for them to focus on the main content.

Alternatively, animation might be scrolling or moving content, and here the restriction is to allow users to complete a task without unexpected changes of context. For example, a news ticker which scrolls automatically should have a pause button, so the user can read each item at their own speed, and be confident it won’t change while they’re reading it! Similar logic applies when large blocks of content, or whole pages, are automatically refreshed. This is common on sites that contain stock information or sports results. You simply shouldn’t do this at all, unless you provide explicit user-control over the refresh frequency (which defaults to never).

But time limits are often an integral part of the activities they’re used for. Many games are inherently timed-based, and removing the time restriction would negate the purpose of the game. In such cases, it’s fair to say that the content simply can’t be made accessible without changing its meaning. The WCAG allows for this possibility, as long as the content is clearly described as such.


We’ve seen how JavaScript accessibility comes down to the following three core principles.

  • All JavaScript functionality must take a form that can be interpreted as text.
  • All JavaScript functionality must be accessible to the keyboard.
  • Time-based activity in JavaScript should be user-controllable, unless that would change its meaning.

Next time, we’ll move on from this theoretical ground, to look at some of the simple, but practical things you can do right now, to make JavaScript functionality more accessible. This is not the realm of narrowly-supported, unproven and bleeding-edge developments, but stuff we’ve been doing for years.

James EdwardsJames Edwards
View Author

James is a freelance web developer based in the UK, specialising in JavaScript application development and building accessible websites. With more than a decade's professional experience, he is a published author, a frequent blogger and speaker, and an outspoken advocate of standards-based development.

Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week
Loading form