Determining whether your website or application is accessible can seem like an overwhelming task. If you're approaching accessibility for the first time, the sheer breadth of the topic can leave you wondering where to start. After all, working to accommodate a diverse range of abilities means there are a correspondingly diverse range of issues to consider.
This post breaks down these issues into a logical, step-by-step process for reviewing an existing site for accessibility.
Start with the keyboard
For users who either can't or choose not to use a mouse, keyboard navigation is the primary means of reaching everything on screen. This audience includes users with motor impairments, such as a repetitive stress injury (RSI) or paralysis, as well as screen reader users.
For a good keyboard experience, aim to have a logical tab order and clearly discernible focus styles.
Start by tabbing through your site. The order in which elements are focused should follow the DOM order. If you're unsure which elements should receive focus, consult the module in the Learn Accessibility course about focus. The best practice is that any control a user can interact with or provide input to should be focusable and display a focus indicator (such as a focus ring).
Custom interactive controls should be focusable. If you use JavaScript to turn a
<div>
into a fancy drop-down, it won't automatically be inserted into the tab order. To make a custom control focusable, give it atabindex="0"
.tabindex
values greater than 0 change the tab order and can be confusing for screen reader users.Make only interactive content focusable. Adding
tabindex
to non- interactive elements like headings slows down keyboard users who can see the screen, and doesn't help screen reader users because the screen reader already knows to announce them.If you add new content to a page, direct the user's focus to that content first so they can take action on it. See Managing Focus at the Page Level for examples.
Design your site so that the user can always focus the next element when they want to. Beware of autocomplete widgets and other contexts that can trap keyboard focus. You can temporarily trap focus when you want the user to interact with a modal and not the rest of the page, but you should always provide a keyboard-accessible way to escape the modal. See Modals and Keyboard Traps for an example.
Make your focus control usable
If you've built a custom control, let your users reach all of its features using only the keyboard. Read Managing Focus In Components for techniques to improve keyboard access.
Manage offscreen content
Many sites have offscreen content that is present in the DOM but not visible, like links inside a responsive drawer menu or a button inside a modal window that hasn't been displayed yet. Leaving these elements in the DOM can create a confusing keyboarding experience, especially for screen readers, which announce the offscreen content as if it's part of the page.
See Handling offscreen content for tips to handle these elements.
Test with a screen reader
Improving general keyboard support lays some groundwork for the next step, which is to check the page for proper labeling and semantics and any obstructions to screen reader navigation.
If you're unfamiliar with how semantic markup gets interpreted by assistive technology, read Content structure.
- Check all images for proper
alt
text. The exception to this practice is when images are primarily for presentation purposes and aren't essential pieces of content. To signify that screen readers should skip an image, set the value to an empty string:alt=""
. - Check all controls for a label. For custom controls, this might require the
use of
aria-label
oraria-labelledby
. See ARIA Labels and Relationships for examples. - Check all custom controls for an appropriate
role
and any required ARIA attributes that communicate their state. For example, a custom checkbox needs arole="checkbox"
andaria-checked="true|false"
to properly convey its state. See Introduction to ARIA for a general overview of how ARIA can provide missing semantics for custom controls. - Make the flow of information through your page make sense. Because screen readers navigate the page in DOM order, they'll announce any elements you've visually repositioned visually using CSS in a nonsensical order. If you need something to appear earlier in the page, physically move it earlier in the DOM.
- Aim to support screen reader navigation for all content on the page. Ensure
no sections of the site are permanently hidden or blocked from screen
reader access.
- If content should be hidden from a screen reader, for example, if it's
offscreen or just presentational, set that content to
aria-hidden="true"
. For a deeper explanation, refer to Hiding content.
- If content should be hidden from a screen reader, for example, if it's
offscreen or just presentational, set that content to
Get familiar with screen readers
Though it might seem daunting to learn a screen reader, they're actually pretty user-friendly. In general, most developers can get by with just a few simple key commands.
If you're on a Mac, check out this video about VoiceOver, the screen reader that comes with Mac OS. If you're on a PC, check out this video about NVDA, a donation supported, open-source screen reader for Windows.
aria-hidden
doesn't prevent keyboard focus
It's important to understand that ARIA can only affect the semantics of an
element; it has no effect on the behavior of the element. You can make
an element hidden to screen readers with aria-hidden="true"
, but that doesn't
change the focus behavior for that element. For offscreen interactive content,
For offscreen interactive content, use the inert
attribute
to make sure it's truly removed from the keyboard flow. For older browsers,
combine aria-hidden="true"
with tabindex="-1"
.
Interactive elements should indicate their purpose and state
Providing visual hints, or affordances, about what a control will do helps a wide variety of people on a wide variety of devices operate and navigate your site.
- Interactive elements, like links and buttons, should be distinguishable from non-interactive elements. It's hard for users to navigate a site or app when they can't tell if an element is clickable. There are many valid ways to indicate interactive elements. One common practice is underlining links to differentiate them from their surrounding text.
- Similar to the focus requirement, interactive elements like links and buttons
require a
hover
state to tell mouse users when their pointer is over something clickable. However, to make these elements accessible to other input methods, they have to be distinguishable without ahover
state.
Take advantage of headings and landmarks
Headings and landmark elements give your page semantic structure, and greatly increase the navigating efficiency of assistive technology users. Many screen reader users report that, when they first land on an unfamiliar page, they typically try to navigate by headings.
Similarly, screen readers also offer the ability to jump to important landmarks
like <main>
and <nav>
. For these reasons it's important to consider how the
structure of your page can be used to guide the user's experience.
- Use the
h1-h6
hierarchy. Think of headings as tools to create an outline for your page. Don't rely on the built-in styling of headings. Instead, treat them as if they were all the same size and use the semantically appropriate level for primary, secondary, and tertiary content. Then use CSS to make the headings match your design. - Use landmark elements and roles so users can bypass repetitive content. Many
assistive technologies provide shortcuts to jump to specific parts of the page,
such as those defined by
<main>
or<nav>
elements. These elements have implicit landmark roles. You can also use the ARIArole
attribute to explicitly define regions on the page, as in<div role="search">
. See Semantics and navigating content for more examples. - Avoid
role="application"
unless you have experience working with it. Theapplication
landmark role tells assistive technology to disable its shortcuts and pass through all key presses to the page. This means the keys screen reader users typically use to move around the page no longer work, and you'll need to implement all keyboard handling yourself.
Review headings and landmarks with a screen reader
Screen readers, like VoiceOver and NVDA, provide a context menu for skipping to important regions on the page. When testing for accessibility, you can use these menus to get an overview of the page and determine if your heading levels are appropriate and which landmarks are in use.
To learn more, refer to these instructional videos on the basics of VoiceOver and NVDA.
Automate the process
Manually testing a site for accessibility can be tedious and error-prone. It's beneficial to automate testing as much as possible. You can use browser extensions and command line accessibility test suites.
- Does the page pass all the tests from either the
aXe
or WAVE
browser extensions? There are other options available, but these extensions
can be a useful addition to any manual test process because they can
pick up on subtle issues like failing contrast ratios and missing ARIA
attributes.
- If you prefer to work on the command line, axe-cli provides the same features as the aXe browser extension, but can be run from your terminal.
- To avoid regressions, especially in a continuous integration environment, incorporate a library like axe-core into your automated test suite. axe-core is the same engine that powers the aXe Chrome extension, but in a command line utility.
- If you're using a framework or library, does it provide its own accessibility tools? For example, the protractor-accessibility-plugin for Angular. Take advantage of available tools whenever possible.
Use Lighthouse to test PWAs
Lighthouse is a tool that measures the performance of your progressive web app (PWA). And, it uses the axe-core library to power its accessibility tests.
If you already use Lighthouse, look for failing accessibility tests in your report. Fix the errors to improve the overall user experience of your site.