Today we'll dive into accessibility, looking at the DOM, assistive devices, accessible content, and automated auditing.
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.
WCAG compliance mandates:
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.
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.
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.
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.
“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.
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.
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.
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.
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.
Mine includes too many browser extensions, a dorky mechanical keyboard, and, sometimes, a text-based browser called w3m Opens in a new window.
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 ![]()
…or this one 
…or this one 
…or this one
Opens in a new window
Aside from keyboard-control and text alternatives to graphics and context, there are a few additional concerns that the specifications consider:
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.
class, alt, targetThis 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.
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…
role attribute to be identifiable to assistive technologiestabindex attribute to become keyboard-focusablekeydown listener for both Enter and SpacebarIf there is a native HTML element whose semantics describe your content, it is very likely accessible by default.
<details style="padding:1rem;">
<summary>Need an accordion?</summary>
<p>Try the <details> element</p>
</details>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>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.
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.
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.
<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".
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:
rolearia‑label, aria‑labelledby, or aria‑controls, can describe an element, or point to a relationship with another element.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.
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…
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.
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
-- h3Alternative 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.
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.
Be on the lookout for images with embedded text, or worse - OCR-resistant PDFs.
Think about what this sounds like: ¯\_(ツ)_/¯.
For the same reason, write "16 to 17 years old" instead of "16-17 years old".
Via sitepoint
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.
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.
See the Pen Hiding Techniques by Simon Borer (@simonborer) on CodePen.
Hiding things, and then showing them on focus comes in handy for the (WCAG required) navigation skip link.
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.
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…
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.
Let's look at some ways different team members can get involved.
Copywriters should be prepared to provide…
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.
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.
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.
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.
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.
/fix-my-a11y.html file you just downloaded.