-
Notifications
You must be signed in to change notification settings - Fork 1
Accessibility
By Corina Murg - github: @CorinaMurg
- What is Accessibility
- Legal landscape in the US for web accessibility
- Assistive Technologies
- How Accessibility Works
- Accessibility guidelines
- Testing for Accessibility: First Steps
In the context of web development, accessibility means that websites and apps are designed and built such that everyone, including people with disabilities, can navigate them and interact with them. The goal of accessibility is for everyone to be able to use the web based on the abilities they have, and not to be excluded due to their disabilities.
For people with disabilities, an accessible website means
- freedom
- privacy
- it can remove challenges associated with their impairments
To improve the business side
- Improved SEO (e.g., when using heading tags)
- Increased market share
- Better overall user experience (e.g., clear navigation, easy-to-read fonts)
1990 ADA (Americans with Disabilities Act) at the federal level
Title III of the ADA: “no individual shall be discriminated against based on disability in the full and equal enjoyment of the goods, services, facilities, privileges, advantages, or accommodations of any

Firms with < $25 million revenue: 77% of all lawsuits
Cases filed in New York: 75% of all lawsuits
Cases with overlay widgets: 933
Accessibility and User Experience
✓ We should not separate usability and accessibility
✓ People interact with the web through different senses ✓ we should not assume that everyone is a sighted mouse user
We expect a user with disabilities to rely on special equipment and software to interact with the web (these are called assistive technologies), but that is not always the case. A person with low vision might just need a good contrast between the text and background colors to be able to see everything on the screen. Some users just need a dark mode setting. A person with good sight but limited hand mobility might just need to use the keyboard instead of the mouse.
In most cases, assistive technologies are used by people with more serious impairments.
A person who is blind relies on a screen reader, a technology that shares the content on the screen. It can do it two ways:
- via a speech synthesizer for the user that has good hearing (the user navigates through the UI elements with the keyboard and the content on the screen is shared with them through synthetic speech)
- via a braille display, for users who are deaf or hard of hearing (The screen reader translates the content on the screen into a format that can be read on a braille display. These displays are fitted with braille cells that change dynamically)
A person with good sight but limited or no hand mobility could use speech recognition software or an eye-tracking system (a device that allows mouse control through eye movements).
The mere presence of an assistive technology to aid a user in interacting with the web is not enough. Our application has to be programmed in a way that takes into account the needs of each group of users, and not just those of the typical user with good sight and good hand mobility. Sometimes, we also have to take into account that assistive technologies are not perfect, and given several choices to program a certain element, use the one that eliminates most barriers or provides a more seamless user experience.
As part of the rendering process, the browser builds the accessibility tree, a simplified version of the DOM tree. The accessibility tree contains only elements that need to be exposed to assistive technologies, like links or headings. Any div element with a purely decorative or container role will be ignored. When triggered, assistive technologies use the browser's accessibility APIs to retrieve information from the accessibility tree and present it to users.
While the DOM tree is structured by HTML tags/elements, the accessibility tree is structured by roles. For each object in the accessibility tree, its role matches the function of its corresponding HTML element.
// DOM tree
<nav>
<ul>
<li>
<a>Home</a>&
</li>
// other list items
</ul>
</nav>
// Accessibility tree
navigation
list
listitem
link "Home" focusable: true focused: true
StaticText "Home"
// other list items
For each object in the Accessible Tree, the browser shares the following:
- name (if there is one!)
- role
- properties (like focusable)
- state (like focused, checked, collapsed, expanded, etc)
<header role="banner">
<p>Put company logo, etc. here.</p>
</header>
<nav role="navigation">
<ul>
<li>Put navigation here</li>
</ul>
</nav>
<main role="main">
<p>Put main content here.</p>
</main>
<footer role="contentinfo">
<p>Put copyright, etc. here.</p>
</footer>
Each assistive technology will use the information from the accessibility tree to present the object to the user in the most appropriate way:
- a screen reader will announce it as a "Home link".
- speech recognition software will recognize it as "Home" and allow the user to activate it with the command "click Home".



An implicit role is assigned by default because it’s built into the definition of the semantic HTML tag used to create the element. When the browser builds the accessibility tree, it assigns the role, and all related properties and states, to the corresponding accessible object.
As developers, we can also explicitly assign a role to an element using a set of special roles and attributes called Accessible Rich Internet Applications, often referred to by the acronym ARIA. These are added to HTML tags to modify or improve the default behavior of an element and make it accessible.
Warning: We should not jump to ARIA right away. When we have to implement a certain functionality and the HTML tag for it exists, we should use the tag. The first rule of ARIA is actually: don't use ARIA! Assistive technologies have a better relationship with semantic HTML than with ARIA, and as we’ll see in the next section, using ARIA does not guarantee the same outcome we would achieve with HTML.
During the construction of the accessibility tree, the browser evaluates each element in the DOM to create its accessible name. If the content of a web page changes dynamically, it updates the accessibility tree accordingly, and the accessible names are recomputed as necessary.
Certain elements (links, buttons, all form elements, headings) must have a name and it has to be descriptive enough to convey the element's purpose.
To create the accessible name, the browser uses the accessible name and description computation algorithm. The algorithm takes into account the visible text or label of the element, but several other attributes are considered as well:

- text defined by a visually-hidden class
This is a CSS class that hides text visually but makes it available to screen readers.
<button>
<img alt="" src="x-mark.svg"/">
<span class="visually-hidden">Close menu</span>
</button>
We have to be careful with it because it won't work easily with speech commands unless the user can tell what the name of the element is.
Also, if the CSS class is not implemented correctly, the spaces between words might be ignored and screen readers could announce the text as a single continuous string. It’s important to give it a certain size (even if it’s 1px) and use
- alt
<button>
<img alt="Close menu" src="x-mark.svg" />
</button>
You can use it with interactive images. With buttons or links that contain an image and no visible text or ARIA attributes, the browser will take the alt attribute to compute the accessible name.
Note that this is slightly more verbose. So, a button wrapping an image of x can have an alt="Close modal" and it will be announced as a "Close modal graphic button". (An image is announced either as a graphic or image, depending on the screen reader.)
Again, a common concern with accessible names not computed from visible text: to activate the element, voice users should be able to tell its name. We have to choose the alt text thoughtfully!
We could also use an empty alt attribute to hide the image from the screen reader and add a visually hidden span with the accessible name.
-
title
We should avoid it because it's tricky to make it accessible to screen reader users. We can still use it to provide a visual tooltip on mouseover, but not rely on it for the accessible name.
Please note this is an attribute that is added to the opening HTML tag of an element. We should not confuse it with the
<title>tag, which is used to provide a title for a web page. - placeholder Technically, this is an option if we have an input with the placeholder attribute. It’s not supported by all browsers though, and it’s not recommended that we use it.
- aria-labelledby It has the highest priority among all the other options, including the visible text. It references the ID of another element that has visual text. The text of that element then becomes the name of the current element.
<h2 id="table-contents">Table of Contents</h2>
<nav role="navigation" aria-labelledby="table-of-contents">
// table of contents links
</nav>
- aria-label
It takes a string value that becomes the name of the element. For example, aria-label="Close survey" could be used to provide the name of a button. Is the main difference with aria-labelledby? It's not visible, and it's only announced to the screen reader user.
<button aria-label="Close menu">
<img alt="" src="x-mark.svg"/>
</button>
The advice from experts is to use it only if nothing else is available. The problem is that it does not take a “lang” attribute nor it's guaranteed to be translated by all browsers. This unfortunately prevents our content from being accessible to a global audience (a process called "internationalization").
Again, this attribute has the usual problem of a name not relying on visible text: voice users will have to guess the name of the element since it's not visible or go through a series of other commands until they can select the element.
Web Content Accessibility Guidelines (WCAG) WCAG 2.2


A
- they provide only the most basic level of accessibility
AA
- it’s the recommended level; it requires that all level A have also been met
AAA
- the desirable level that will benefit the largest number of users
- 1994: W3C (World Wide Web Consortium)
- 1997: WAI (Web Accessibility Initiative )
- 1999: WCAG 1.0
- 2008: WCAG 2.0 with 12 guidelines, 61 success criteria
- 2018: WCAG 2.1 with 1 guideline, 17 success criteria
- 2023: WCAG 2.2 with 9 success criterion, one success criteria deprecated
Automated (with browser extensions)
- Google’s Lighthouse
- Deque’s axe DevTools
Linter
- axe Accessibility Linter
Continuous Accessibility
- Using e2e testing with a focus on users with disabilities
Manual testing
- navigating with only the keyboard, using different assistive technologies etc
User testing
- involving people with disabilities in the process of evaluating the site
To summarize the accessible name computation:
- If there's no visible text (or label), or at least text with a visually hidden class, the algorithm relies on the content of certain HTML (alt, title) and ARIA (aria-labelledby, aria-label) attributes.
- The ARIA attributes are given priority even when the element has visible text or a label. The idea was that they were added to offer a more descriptive or tailored name for the element. So, if the element has descriptive visible text/label, we should not add aria-labelledby or aria-label since they will override the visible text/label.
Accessing the accessibility tree in Dev Tools video from Google: