Today we'll dive into accessibility, looking at the DOM, assistive devices, accessible content, and automated auditing.

Table of Contents

Accessibility overview

Accessibility is both a philosophy, and a legal requirement.

Philosophy: universal design, removing barriers and creating equity.

Law: The Access for Ontarians with Disabilities Act, in accordance with the Canadian Charter of Rights and Freedoms, mandates a level of WCAG compliance.

A few things I think about
when I think about web accessibility:

  • The website's user interface is not the users' user interface.
  • The whole point of the internet is interoperability.
  • Whether or not you think people are a good thing, our forté as a species is not in individuals, but in being a group.
  • I frankly don't care if people are productive. Putting up barriers is for jerks.
  • A thing you can tell your boss: why do you hate money?

How we follow the WCAG guidelines

WCAG compliance mandates:

  • semantics,
  • proper source order,
  • content considerations,
  • text alternatives to visual information,
  • accommodations for colour-blindness and low visual acuity,
  • keyboard-only functionality, and
  • the use of the WAI-ARIA specification.

Over the next couple weeks, we'll talk about how we accomplish each one of these things, but most of it is pretty simple: use html as it was intended, don't limit the user's choice of input device, and don't rely solely on what's visually shown to convey any information.

Before we talk about exactly how we avoid putting up barriers, let's talk about the different ways people are going to access your content.

Assistive Devices

The point of the internet is accessibility.

The web was conceived as a way of making information accessible. The end-user can use whatever software or hardware they want. Information is encoded in a standardized way so that the recipient of that information can interact with it however they see fit. This is the core principle of the internet.

If you understand this principle, then you understand "A11y" - web accessibility.

This principle of predictable encoding is what allows the internet to be accessible via refrigerator.

Samsung Family Hub 2.0 refrigerator with built-in touch screen
Note: Samsung is not a sponsor.

It also allows for a machine-readable internet powered by web‑crawling search engines, who can parse content and rank its relevance.

This principle is similarly responsible for the longevity of websites last updated in the mid-1990s.

Space Jam website

The point of the internet is to be accessible on Windows and Macs, on Netscape and Firefox and Chrome, phones and tablets and watches and treadmills.

The way this works is through the use of a markup language, HTML. HTML tags wrap content to communicate the type and purpose of content.

<blockquote>
    This is a quote.
    <cite>This is the citation</cite>
</blockquote>

The purpose of encoding the internet using a standardized markup language is to make our content client-agnostic. We encode the intention of our content, be it a link, a document heading, an input field. This allows the receiving technology - the client - to render our content however it wants.

The end-user's technology stack

“It works on my machine.”

- Every developer, at some point.

If the idea of the internet is to allow the user to consume your content using whatever technology they see fit, then every developer must, at some point, come to terms with the fact that other people exist.

While developers develop, we keep track of our progress by looking at the end-result of our work, and we see it on our own monitors, interact with it using our own keyboards and mice, and look at it with our own eyes. This is all fine and good and necessary.

This only becomes a problem when we forget the fact that what we are building is not only for our own computers, keyboards, mice, eyes, preferred browser, etc. etc.

Responsive website mockup

This issue is, of course, not limited to developers. It arises, for example, when a designer provides a design in specific "desktop" and "mobile" sizes, but fails to consider issues that might come up at other sizes or zoom settings.

It arises when a copywriter over-uses idiom or jargon, or a product manager creates personas that ignore the fact that > 1 in 5 Canadians have a disability Opens in a new window.

In 2017, 6.2 million (22%) Canadians aged 15 and older had a disability. 24% women; 20% men; 13% youth aged 15 to 24; 20% working-age adults aged 25 to 64; 38% seniors aged 65 and older.
Via Statistics Canada Opens in a new window

For those of us who make things on the internet, to understand what we are building, we must understand the problem we are solving, a challenge that is a function of our own frame of reference.

This problem is this: we cannot dictate the technologies of our end‑user.

And, if we borrow from Marshall McLuhan, we can say that technologies are extensions of our selves. We take the problem one step further and say that we cannot dictate the end-user in either their technology or corporal faculties.

Marshall McLuhan leaning on a TV. The TV is showing an image of Marshall McLuhan.

Once we start trying to solve that problem, we are building the internet as intended - accessibly.

"You can only view this website in Internet Explorer"; "you can only view this website on desktop"; "you can only view this website with your eyes" - these are all the same problem, and can all be solved by understanding the product we build when we build the internet.

Edvard Munch's 'Anxiety' - a very anxious painting.
(Team photo)

It may seem like an overwhelming problem - having to consider the endless diversity of technologies, both present and future, even before we add in the endless spectrum of human ability.

Luckily, there is an inherent limit to this problem. Part of the burden is on the end-user.

We do not have to print physical copies of a website for people who do not own a computer. All we have to do is use our markup language to encode our content in a predictable way.

This is what allows the end-user to customize their personal technology stack in whatever way they see fit, given the resources (and the standards) at hand.

That stack includes hardware and software, network provider, and computer peripherals.

A text-based browser, w3m, showing the Princess Margaret Wikipedia page.

Mine includes too many browser extensions, a dorky mechanical keyboard, and, sometimes, a text-based browser called w3m Opens in a new window.

Computer mouse Computer keyboard
Two popular assistive devices

People are accessing your web content with assistive devices. The beauty of writing your code to standards is you don't need to know which devices.

It could be this one…

…or this one
Sip-and-puff system

…or this one
Braille keyboard

…or this one
Big red button

…or this one
Braille phone Opens in a new window

Barriers beyond blindness

Aside from keyboard-control and text alternatives to graphics and context, there are a few additional concerns that the specifications consider:

  • flashing content can trigger seizures,
  • information encoded in colours can be inaccessible to colour-blind users,
  • users may zoom into your content (even more than you'd think),
  • poor colour-contrast can be challenging to read,
  • obtuse or overly complicated language can obscure content,
  • time-based interactions can be a barrier for those with cognitive or motor impairments.

The DOM API

How is it that our code can rise to meet all these wonderful devices? Via the DOM API!

Both 'DOM' and 'API' are acronyms that get thrown around a lot. Let's quickly make sure we all know what they mean.

An Application Programming Interface is a user interface, where the user is a person writing a computer script. It provides you information and functionality from the document or application that you're interacting with.

The Document Object Model is an API that represents an HTML (or XML) document as a traversable tree structure. The elements (and attributes, including text content) within that structure are referred to as 'nodes'.

The DOM API is how JavaScript (or any other scripting language that interfaces with your HTML) "thinks" about your document.

You know how in JavaScript, just about everything is an "object"?

var basicallyEverything = {
    property: "some value ",
    otherProp: "some otherVal ",
    someMethod (someParam) {
        return someParam + " some return value";
    }
};

And we access objects like this:

console.log(basicallyEverything.property +
  basicallyEverything.someMethod("whatever"))
// Outputs "some value whatever some return value"

Well, the Document Object Model is everything in an HTML page - not just the content, but all the properties of the elements as well - turned into an object like that. Try running this command in your browser console on any page:

console.log(window)

It outputs almost a thousand different properties, functions, and nested objects! Every element on every HTML page has their own properties.

Of course, you've accessing the DOM API since the first day you wrote

document.getElementById("myFirstId");

…or…

console.log(window.location.href);

But the DOM API isn't just for us to mess around with - it's there so our users can access and manipulate our content in whatever way they see fit.

When we add attributes to HTML elements, what we're really doing is adding more information to the DOM.

console.log(
  document
    .getElementById("myImage")
    .attributes
    .alt
    .textContent
);

There are different kinds of attribute values we can assign to DOM nodes.

native attributes
provided by the HTML spec, e.g. class, alt, target
data attributes
user-customizable
ARIA attributes
ARIA (Accessible Rich Internet Applications) provides contextual information about the purpose of things, along with if and how DOM nodes can update, and what happens when they do.

This is all a very fancy way to say: "if you add these special attributes to your code, assistive devices can understand it better".

<div aria‑label="I'm extra accessible!">Content</div>

Okay, one thing I want to clear up before we dig in - accessibility lives or dies in the front-end. Your front-end might be assembled by a server side language, a user might trigger error messages from the API, but all that matters is the content delivered to the user.

Native accessibility

It's pretty common for people to take for granted the amount of functionality we get "for free" when we use semantic HTML.

Just as a small example, compare a <button> element to a <div> pretending to be a button…

Obviously the <div> requires some CSS to replicate the style, but more than this, it needs…

  • the role attribute to be identifiable to assistive technologies
  • the tabindex attribute to become keyboard-focusable
  • several CSS properties to mimic the native cursor behaviour, text properties and visual state changes
  • a keydown listener for both Enter and Spacebar

If there is a native HTML element whose semantics describe your content, it is very likely accessible by default.

People sleep on HTML

<details style="padding:1rem;">
    <summary>Need an accordion?</summary>
    <p>Try the <details> element</p>
</details>
Need an accordion?

Try the <details> Opens in a new window element

        <label>What about auto-complete?
    <input list="example-datalist">
    <datalist id="example-datalist">
        <option value="Yes">
        <option value="No">
        <option value="Ontario">
        <option value="Cambodia">
        <option value="Canada">
    </datalist>
</label>
    

How about a meter?

<label for="volume">Volume</label>
    <input 
        onchange="const f=document.getElementById('outputMeter');f.setAttribute('value', this.value),document.getElementById('outputText').innerHTML=`${this.value}`;" 
        type="range" 
        id="volume" 
        min="0" 
        max="100" 
        aria-controls="outputMeterRegion">
<div role="region" aria-live="polite" id="outputMeterRegion">
    <label for="outputMeter">Output meter set at <span id="outputText">50
    <meter id="outputMeter" min="0" max="100" low="33" high="66" optimum="80" value="50">
</div>
(Okay that last one cheats a little - supplementing the default behaviour with a single line of javascript and an aria attribute.)

Every HTML element except <div> & <span> have a semantic meaning. In other words, your HTML is already communicating with the client (browser, screen reader, web crawler, et al.) about your content. Provided you are not using your elements in a semantically incorrect way, your elements are already doing a lot of heavy lifting for you.

This is the purpose of the structural elements introduced in HTML5. Elements like <nav>, <header>, <main>, <footer> etc. communicate document structure to the client.

This is also why heading tags (<h1>, <h2>, et al.) are not meant to be used for styling - they communicate how the content is organized, and this organization is not just announced by the screen reader, but are an option for navigating through the document.

WAI-ARIA

The WAI-ARIA specification allows us to supplement our HTML elements, widgets and document presentation by defining roles and properties for screenreader users.

This is especially important when updating content on the page without a location change or page refresh, which is a common practice when using modern front-end JavaScript frameworks, such as React, Vue and Angular.

When to use ARIA

  1. There is visual information on the page that has no native text alternative format, or
  2. There is a DOM node (including text) that can or does update without a page refresh being triggered, and
  3. There is no native semantics or attribute available.

Visual information with no native text alternative format

What do we mean by this? Well, the obvious example of visual information is an image, but it has a native text alternative format - the alt attribute.

A 'close' button represented by an 'x'
In this instance, X is going to take it away from ya.
<button 
  aria‑label="Close" 
  onclick="myDialog.close()">X</button>

One instance of visual information not having a native text alternative is when we use symbols (including alphanumeric characters) to represent an available action that makes sense in a visual context (like a dialog), but may not make sense if the user just hears their screenreader say "x".

What ARIA attributes should I use?

You can find a pretty comprehensive list on MDN Opens in a new window, and we'll be doing a deep dive next week.

There are a lot, but you should know about the role attribute, which overrides or supplements native HTML semantics, and state attributes including aria‑live, aria‑expanded, and aria‑hidden (which differs from the native hidden attribute).

The ARIA spec has their own taxonomy, but for now let's say there are three categories:

role
Supplements or overrides native semantics
labelling attributes
Attributes like aria‑label, aria‑labelledby, or aria‑controls, can describe an element, or point to a relationship with another element.
state attributes
Attributes like aria‑live, aria‑expanded, or aria‑busy, can be updated with JavaScript to communicate the state of content.

That's enough on aria today - we'll be looking at it more over the next two weeks, so don't feel like you need to memorize the whole list Opens in a new window right now.

For the rest of today, let's take a step back and look the most basic element of accessibility: our static content.

Making content accessible

We can provide alternatives to this visual information (including information communicated through layout) with alt attributes for graphic content, scope and caption for tables, and labels or screen reader-specific content for inputs, buttons and links.

We must also keep in mind that our elements are often used as navigational landmarks for people using non-visual clients, including headers for document structure.

Text alternatives are provided when information is presented visually - this includes images, graphs, charts and tables, but also cases where elements have implicit functions based on the visual design, i.e. buttons within a form.

Refer back to our Week 1 "Component of the Week" Opens in a new window for a refresher on text alternatives.

Accessible text content means…

  1. Unique page titles (as it can be difficult to assess if the page has actually changed otherwise)
  2. Concise link text (as screen readers read them in their entirety)
  3. Text-based information about link behaviour
  4. Skippable navigation
  5. Captions, transcriptions and other alternative text that provide an alternative to all relevant visual information
  6. Verbose error messages (that capture focus), and
  7. Using words rather than ASCII symbols

Page titles

The text in the <title> element in the head of your HTML document is the first content that is read out by a screen reader when they land on your page.

Page titles should be unique and descriptive. If it's page 2 of 3, say so.

Headings

Heading elements (<h1>, <h2>, etc.) are important tools used for page navigation when using assistive technologies.

Headings should structure your document. Think of the way your information is structured - it's very rarely appropriate to have just an h1 and then p tags all the way down. Headings should provide meaning and context.

It can be tempting to use heading elements for their style attributes. That's all well and good until you start breaking semantics. Use CSS to style headings however you like, but maintain your document's structure.

h1
- h2
-- h3
-- h3
- h2
-- h3
--- h4
-- h3

Alt text

Alternative text should be your best effort to convey all of the relevant information in the image - no more, no less. This gets tricky when you get into things like graphs, but remember what we talked about when the image was our "Component of the Week" - alternative text should describe the meaning the user is meant to take away.

Transcripts and captions

Audio and video need transcriptions and/or captions. Keep an ear out for sounds that convey relevant information, and make sure they're included - not just the words.

Beware things that look like text

Be on the lookout for images with embedded text, or worse - OCR-resistant PDFs.

An image with embedded text

ASCII

Think about what this sounds like: ¯\_(ツ)_/¯.

For the same reason, write "16 to 17 years old" instead of "16-17 years old".

Because not all visual impairments require the use of a screenreader, we provide alternatives to colour cues for people with colour-blindness (i.e. focus outline, proper labelling), and for people with reduced visual abilities we check our colour contrast ratios and test our websites for up to 400% zoom.

Not sure if you colour contrast is up to snuff? The quickest way to check is by clicking on the text's "colour sample" in your browser tools.

Semantic HTML

Accessible documents are traversable - you can move through them with the keyboard or a scripting language the same way (and in the same order) you move through them with your eyes.

Semantics in HTML refers to using native elements and attributes for their defined purpose.

A correct source order means that the visual flow of the document matches the source code.

Showing & hiding

See the Pen Hiding Techniques by Simon Borer (@simonborer) on CodePen.

Focus-ability and tab order

tabindex is an attribute that specifies focus-ability. Focus is usually stepped through with the tab key, hence the name.

tabindex="-1" is focusable, but not sequentially. As in, you can`t tab to it.

tabindex="0" means that the element is focusable in the normal tab sequence.

tabindex="1", or any other positive value, means that this element takes precedence over any other element without a declared tabindex. If you are using this, that's a bad sign.

Remember not to confuse the visual order with the DOM order!

Declaring a tabindex value can affect scrolling behaviour on child elements Opens in a new window.

For people with motor-impairment issues, we ensure that we do not disable the native functionality of our proper semantic HTML, and where native functionality is not available, we create keyboard events to supplement our click events.

We also maintain our tab order by having our source order properly represented.

On those rare occasions where our visual order and source order are in conflict, we can control focus with JavaScript.

Where we want to make an element focusable that does not have native focus-ability, we can use the tabindex='0' attribute value.

Mobile/touchscreens

Of course we keep in mind that all these standards apply whether on a desktop or mobile device, with a few special considerations for mobile, including…

  1. Maintaining keyboard functionality
  2. Supporting different orientations
  3. Touch target size and spacing
  4. Gesture alternatives, and
  5. Appropriate virtual keyboard data types.

Accessibility workflow

Planning for accessibility involves the entire team - developers, yes, but also design, content, and management. Once team members each understand the role they play in producing accessible content, it's possible to build, audit, fix and track your progress over time.

A team-based approach to content

Let's look at some ways different team members can get involved.

Project manager

  • Assume you have a diverse user base, and develop personas accordingly. If you don't have a diverse user base… maybe there's a reason?
  • In the hiring process, do not seek out team members with disabilities so that you can dump responsibilities on them, but do consider diversity an asset.
  • Consider user testing with people using their own personalized technology stack, such as people who use assistive reading devices, people with color blindness impairments, or people with motor impairments.
  • Insist on accessibility testing as a standard part of the development lifecycle.
  • Get familiar with the accessibility opportunities that go with each role in your team. For example, you might consider taking the free "Web Accessibility by Google" Udacity course Opens in a new window.

Project manager (continued)

Design

Content

Copywriters should be prepared to provide…

  • alternative text for images (not always easy - consult the W3C's alt text decision tree Opens in a new window)
  • link context
  • headings to structure content
  • unique page titles
  • captions or transcriptions for audio-visual content
  • form labels, instructions and error messages

While not required by the AODA, WCAG Level AAA requirements include considerations when using unusual words and abbreviations, as well as for reading level and pronunciation.

Accessibility within the team

All content considerations for the web can also apply to documents within the office - spreadsheets, PDFs, text documents, and slideshows included.

While we don't have time to cover all of these today, getting familiar with making accessible web content will also teach you how to make accessible documents. In the Microsoft Office suite of tools (Word, PowerPoint, etc.), there are built-in accessibility checkers Opens in a new window, and most common office formats take accessibility in mind, like Adobe PDFs Opens in a new window and Google Docs, Slides and Sheets Opens in a new window.

In other words, you are not alone. Making good content is a team effort. You can't make a site accessible by yourself. But they can't do it without you either.

Want to be safe?

TEST 

I can't emphasize enough how important it is to test. That's why there are QA departments. It is wonderful to follow best practices, but even when specification documentation is perfect (it's not), and even when you limit your scope to the latest versions of a few popular clients (don't), and even when your linters catch all the edge cases (they won't), you still makes mistakes.

Auditing

Over the next couple weeks we'll learn why accessibility auditing can never be fully automated, but today, we're going to look at two handy, light-weight tools for quickly checking to see if there are any obvious accessibility errors on a page.

Open Chrome, and open the developer tools.

Across the top, you'll find an option called 'Lighthouse' (or 'Audits' in older versions of Chrome).
For our purposes today, you can deselect all the audits aside from 'accessibility', and run the test on 'desktop'.
Click 'generate' and get the results!
Of course, if you don't get a score of 100%, you can see where "points" were deducted, and learn more about how to fix those violations.

Lighthouse isn't the best Opens in a new window tool out there, though. Deque Opens in a new window is widely considered the industry leader in accessibility consulting. They built the open-source ruleset Opens in a new window that the Lighthouse accessibility audit and Microsoft's Accessibility Insights for Web are based on, and their own browser extension Opens in a new window is considered the best tool for automated auditing of single pages.

Let's try it out!

  1. Download this HTML document Downloads a web page, or opens in a new window.
  2. In VS Code, use the Live Server extension to serve the /fix-my-a11y.html file you just downloaded.
  1. Now you should be able to access your files (via something like http://localhost:1337/fix-my-a11y.html), and run the aXe browser extension to diagnose errors.
  2. Open the downloaded html document in a code editor, and alter the HTML until you've resolved all the errors.