You're only supposed to blow the bloody doors off!

You're only supposed to blow the bloody doors off!

ConFoo, Montreal 2018

LĂ©onie Watson ~ The Paciello Group (TPG)

You're only supposed to blow the bloody doors off!

Screen readers

Software that translates on-screen content into synthetic speech

Jaws NVDA Voiceover Narrator

Screen reader demo: text

Screen reader demo: headings

Screen reader demo: forms

Keyboard intercept chain

Windows
Screen reader
Browser
Mac OS
Browser
Screen reader

Virtual/browse mode

Windows screen readers create a virtual copy of the browser contents

Forms/focus mode

Windows screen readers pass keys straight through to the browser

JavaScript keyboard shortcuts

Screenshot of Twitter keyboard shortcuts dialogue

JavaScript keyboard shortcuts: problem

JavaScript keyboard shortcuts: solution

Platform controls

Windows 10 bold checkbox
Role
checkbox
Name
Bold
State
Focusable, Focused, Checked

Accessibility APIs

Windows
UI Automation (UIA)
MS Active Accessibility (MSAA)
IAccessible2 (IA2)
Mac OS
OSX Accessibility Protocol (AXAPI)
Linux
Accessibility Toolkit (ATK)
AT Service Provider Interface (AT-SPI)

Web controls

<label for="this">Bold</label>
< type="checkbox" id="this" checked>
Role
checkbox
Name
Bold
State
Focusable, Focused, Checked

Accessibility mappings

Define how role, state, properties, and keyboard focus for native elements are handled in the browser

DOM tree

DOM information for an HTML checkbox

Accessibility tree

Accessibility tree information for an HTML
checkbox

HTML mapping support

Browsers may support an element, but not accessibility support it

A browser may accessibility support an element, but a screen reader may not

Manipulating the DOM

Polyfill accessibility

When native accessibility information is unavailable

ARIA: don't use it

Use native HTML whenever possible

Native HTML

<button>Tequila!</button>

var button = document.getElementById('button');
button.addEventListener('click', doSomething, false);

Screen reader demo: native HTML

ARIA: unless you need to

When repurposing elements like <div> and <span>

Missing semantics

<span id="button">Tequila!</span>

Keyboard demo: missing semantics

Tequila! button

Screen reader demo: missing semantics

With added semantics

<span id="button" role="button" tabindex="0">Tequila!</span>

Screen reader demo: with added semantics

ARIA: don't break native semantics

<button role="heading" aria-level="1">Tequila!</button>

Screen reader demo: broken semantics

ARIA: make it work with a keyboard

When you create custom components it's your responsibility to make it work with the keyboard

Supplement existing interaction

<a href="#here" id="button" role="button">Tequila!</a>

var button = document.getElementById('button');
button.addEventListener('keydown', function(event) {
    if (event.keyCode == 13) {
        doSomething();
    }
});

Provide all interaction

<span id="button" role="button" tabindex="0">Tequila!</span>

var button = document.getElementById('button');
button.addEventListener('keydown', function(event) {
    if (event.keyCode == 13 || event.keyCode == 32) {
        toggle();
    }
});

Screen reader demo: provide all interaction

Using the application role

<body role="application">...</body>

Removes the screen reader from the keyboard intercept chain

Roles that trigger applications mode

Many ARIA roles trigger applications mode automatically, including:

Application mode: tablist

<ul role="tablist">
  <li role="presentation">
      <a role="tab" href="#p1" aria-selected="true" aria-controls="p1">Blanco</a>
  </li>
  <li role="presentation">
    <a role="tab" href="#p2" aria-selected="false">Reposado</a>
  </li>
  ...
</ul>

Screen reader demo: application mode with tablist

Keyboard focus: roving tabindex

Focus management example: roving tabindex

<ul role="tablist">
  <li role="presentation">
      <a role="tab" href="#p1" aria-selected="true" aria-controls="p1">Blanco</a>
  </li>
  <li role="presentation">
      <a tabindex="-1" role="tab" href="#p2" aria-selected="false">Reposado</a>
  </li>
  ...
</ul>

Keyboard interaction: event listeners

Listen for keydown and capture keycodes:

Screen reader demo: application mode with tablist and keyboard interaction

Accessibility Object Model (AOM)

JavaScript accessibility API for the future

ChromeFirefoxSafari

AOM: phases

  1. Modify accessibility node semantics
  2. Respond to events from screen readers (and other ATs)
  3. Create virtual accessibility nodes
  4. Query the accessibility tree

You're only supposed to blow the bloody doors off!

Thank you