The provided content discusses best practices for enhancing web accessibility by implementing JavaScript with a focus on keyboard navigation, semantic HTML, and dynamic content updates for screen reader users.
Abstract
The article emphasizes the importance of making JavaScript components accessible to ensure that websites and web applications are usable by people with various disabilities. It covers tips for improving keyboard navigation, making non-focusable elements focusable, managing focus with JavaScript, and using correct semantic elements. The author also highlights the significance of informing screen reader users about dynamic content changes using ARIA Live Regions and provides examples and resources for creating accessible modal dialogs, buttons, and other interactive components. The article advocates for leveraging JavaScript to enhance accessibility, referencing the WAI-ARIA Authoring Practices for guidance on accessibility patterns, and encourages developers to consider all users when designing and developing web interfaces.
Opinions
The author believes that JavaScript can be used to improve accessibility when implemented correctly.
Accessibility is not just about supporting users with disabilities but also about ensuring usability across different browsers, devices, and internet connections.
Using the correct semantic HTML elements is crucial for accessibility, and developers should avoid using non-semantic elements like <div> or <span> for interactive components.
The author stresses the importance of focus management and suggests using tabindex to make elements focusable and navigable via keyboard.
Screen reader users must be informed of content changes, and the author recommends using ARIA Live Regions to achieve this.
The author suggests that developers should use the <button> element for buttons instead of generic elements like <div> or <span> to ensure proper functionality and accessibility.
The article conveys that developers should not only focus on critical accessibility features but also be polite to users by not interrupting their screen readers unnecessarily with alerts.
The author provides a recap of the importance of JavaScript in enhancing accessibility and encourages continuous learning and application of inclusive design patterns.
The author expresses gratitude to Heydon Pickering and others who contributed to the article and the broader accessibility community.
Writing JavaScript with accessibility in mind
Tips on how to improve the accessibility of your JavaScript components and provide users with more and better ways to interact with your website or web app.
In my first post Writing HTML with accessibility in mind I explained why and how I got started with web accessibility. I also shared some tips on how you can improve your markup in order to make your websites more accessible. Some of these were pretty basic but nevertheless valuable. It all boils down to two of the most important unwritten rules in front-end development: Learn the basics and take enough time to plan and write HTML. Both you and your users will benefit from clean and semantic markup.
Luckily, HTML is not the only language we have to make websites, but the more complex the language, the easier things can go wrong and JavaScript can get very complex. Whilst being content that our code works, it’s easy to forget about users with other input devices than a mouse or touch pad, e.g. keyboard or screen reader users. In this second article of four about web accessibility I have gathered some tips on what to consider when writing JavaScript and how to make your JavaScript components more accessible.
JavaScript is not the enemy
Before you read my tips I want to point out one important thing: Making an accessible site doesn’t mean that you have to decide whether to use JavaScript or not. Accessibility is about making content available to as many people as possible, which also includes users with old browsers and computers, slow internet connections, strict security restrictions (e.g. no JavaScript) and so on. The experience under conditions like these where JavaScript may not work or take too long to load might not be ideal but is still good enough if the website is accessible and usable.
If JavaScript is executable it can even be used to improve accessibility. Sara Soueidan has written about her experiences with creating a tooltip widget in „ Building a fully-accessible help tooltip …is harder than I thought.“. She explains how every „single no-JS solution came with a very bad downside that negatively affected the user experience“ and why JavaScript is important for accessibility.
It’s important to make sure that our websites are navigable by keyboard. A lot of users rely on a keyboard when they surf the web. Among them are people with motor disabilities, blind people and people who don’t have hands or cannot use a mouse or track pad for whatever reason.
Navigating a site via keyboard means jumping from one focusable element to another in DOM order. This is usually accomplished by using the Tab key or Shift + Tab for the reverse direction. Focusable elements are amongst others links, buttons and form elements. They can be selected with the Enter key and sometimes the Spacebar. By being focusable and selectable in different ways they come with very useful default functionalities. Therefore it just makes sense to use correct semantic elements and write HTML in a logical order.
Elements like <p>, <h2> or <div> cannot be focused by default. We often use tags like these to create custom components powered by JavaScript, which might be problematic for keyboard users.
Making non-focusable elements focusable
It’s possible to make non-focusable elements focusable by adding the tabindex attribute with an integer value. If the value is set to 0 the element becomes focusable and reachable via keyboard.
If the value is a negative number, the element is focusable (e.g. with JavaScript) as well, but not reachable via keyboard. You can also use a value greater than 0, but that changes the natural tab order and is considered an anti-pattern.
Even if elements are focusable, sometimes they are not in the right DOM order. To illustrate that I created a simple modal window component in HTML, CSS and JS (Demo and editable Pen).
If you use the Tab-key to jump to the button and press enter, a modal window will pop up. If you press the Tab-key again, the focus will jump to the next link visually below the modal window. The expected behavior would be that the next focused element is within the modal window. But it's not because elements are focused in DOM order and the modal window is located at the bottom of the document. You can see that in action in the following screen recording.
To fix that you have to make the modal window focusable and then focus it with JavaScript.
// Use the focus() method to set focusfunctionshowModal() {
...
var modal = document.getElementById('modal2');
modal.focus();
...
}
You can see that in action in the updated example (Demo and editable Pen) by tabbing to the button, pressing enter and tabbing again. You’ll see that the modal window itself is focused now.
This is great, but there are still two issues here.
If you close the modal window by pressing Esc the focus is lost. Ideally, the focus would jump back to the button where it was before you opened the modal window. In order to achieve that you have to store the last focused element in a variable.
document.activeElement gives you the current element in focus.
// Variable for storing the last focused elementvar lastFocusedElement;
functionshowModal() {
...
// Store the last focused element
lastFocusedElement = document.activeElement;
var modal = document.getElementById(modalID);
modal.focus();
...
}
Now that you have a reference to the button you can focus it again when the modal window is closed.
functionremoveModal() {
...
// Return the focus to the last focused element
lastFocusedElement.focus();
...
}
I’ve updated the code in another Pen (Demo and editable Pen). The accessibility is way better now, but there’s still room for improvement.
It’s advised to the keep the focus within the modal window when it’s opened. Right now it’s still possible to tab out of the modal.
I won’t go into detail here, but for the sake of completeness I made a fourth Pen with a so called keyboard trap (Demo and editable Pen). The focus will stay within the modal window as long as it is active.
If you compare the first and the last Pen you will see there isn’t a lot of extra code. It’s probably not perfect, but the final solution is much nicer to use.
I made a Pen (debug mode / Pen with code) to illustrate some of the issues of using a span or div as a button over a button or input element. If you tab through the page you will experience that you can focus the first button, but not the second one. The reason for this is – of course – that the first button is a button and the second one a div. You can work around that issue by adding tabindex="0" to the div, which makes an initially non-focusable element focusable. That's why the third and fourth button are focusable even though they're divs.
// Button and focusable
<button class="btn">I'mabutton</button>
// Div and not focusable
<div class="btn">I'madiv</div>
// Still just a div, but focusable
<div class="btn" tabindex="0">I'madiv</div>
// Button role and focusable
<div class="btn" tabindex="0" role="button">I'madiv</div>
The div-button is indeed focusable but still behaves like a div, even if you add a role of button. To illustrate that, I added a simple click event handler to all .btn elements (Pen). If you click the buttons an alert box will pop up, but if you try do the same using keys (Enter or Spacebar), only the first button will trigger an event. You would have to add a key event handler to the div-buttons to fully mimic the default button behavior, which seems like a lot of unnecessary overhead, doesn't it? That's why you should use the <button> element if you need a button.
Screen reader users must be informed when content changes dynamically
Usually, screen readers only announce content when an element is focused or the user uses his/her screen reader’s own navigation commands. If content is loaded dynamically and inserted into the DOM, only sighted users will be aware of the changes. ARIA Live Regions provide several options to work around that issue. I’ll show you how in an example.
Let’s say you have a profile settings page where you’re able to edit personal data and save it. When the save button is clicked changes are saved without reloading the page. An alert informs the user whether the changes where successful or not. This may happen immediately or take some time. I recorded a quick video to show you what I just explained.
You can see that the action was successful, but you can’t hear it. Screen reader users won’t notice the change, but there’s a simple solution for this issue. By adding a role of status or alert to the message box screen readers will listen for content updates in that element.
If the text of the message changes the new text will be read out. You can see and hear that in action in this video and take a look at the code in this Pen.
Be polite to your users
The difference between status and alert is that an alert will interrupt the screen reader if it's in the course of announcing something else. status will wait until the screen reader has finished announcing.
There’s another attribute called aria-live, which can take three possible values off, polite or assertive. off is the default value, aria-live="polite" is equivalent to role="status" and aria-live="assertive" to role="alert". In some “well-known predefined cases it is better to use a specific provided “live region role””. Also if a browser doesn't support role you may want to try using both attributes. Léonie Watson shared some test results in „Screen reader support for ARIA live regions“.
<div role="alert"aria-live="assertive"></div>
Sometimes it makes sense to announce more than just the content that has changed
By default screen readers only present content that has changed, even if there is other content within the same live region, but it occasionally makes sense to announce the whole text.
It’s possible to change the default behaviour with the aria-atomic attribute. If you set it to true, assistive technologies will present the entire contents of the element.
Live Regions do not move focus, they just trigger announcement of text
Use alert only for critical changes. status is better in most cases, because it's politer.
Avoid designing alerts that disappear automatically because they may disappear too quickly
During my tests, I had issues with VoiceOver. Hiding the alert using CSS or creating it dynamically didn’t work all the time. Make sure you test your Live Regions thoroughly in different browsers with different software.
You don’t have to guess which usage patterns your widgets must provide
It’s often hard to think of all the features a widget must provide in terms of navigation and accessibility. Gladly there’s a resource called WAI-ARIA Authoring Practices 1.1 that helps us with that. „WAI-ARIA Authoring Practices is a guide to understanding how to use WAI-ARIA to create an accessible Rich Internet Application. It describes recommended WAI-ARIA usage patterns and provides an introduction to the concepts behind them.“
They have guides for building accordions, sliders, tabs, and more.
Accessible JavaScript components
There are also great resources with accessible JavaScript components.
If you know additional resources please share them in the comments.
Recap
Leverage the advantages of JavaScript to improve your site’s accessibility. Take care of focus management, inform yourself about common usage patterns and consider screen reader users when you manipulate the DOM. Above all don’t forget who you are making websites for and have fun while you’re at it.
Going beyond
That’s it for now. I hope that these tips will help you write more accessible HTML. A big thanks to Heydon Pickering, because his book „Inclusive Front-End Design Patterns” built the foundation of most of the stuff that you’ve just read. If you want to learn more about accessibility and inclusive design I highly suggest you read his book.
More accessibility tips
This article is the second one in a series of four. The others are in the works and soon to be released.