Dev Days, Vilnius May 2019
Léonie Watson, TetraLogical
Chrome | Edge | Firefox | Safari |
(Google) | (Microsoft) | (Mozilla) | (Apple) |
Jaws | NVDA | Voiceover | Narrator | Orca |
(Freedom Scientific) | (NV Access) | (Apple) | (Microsoft) | (GNOME) |
Screen readers consumed the HTML directly from the browser, and created a virtual model of the content
Screen readers began using platform accessibility APIs to query information from the browser
UI Automation (UIA) MS Active Accessibility (MSAA) IAccessible2 (IA2) |
OSX Accessibility Protocol (AXAPI) |
Accessibility Toolkit (ATK) AT Service Provider Interface (AT-SPI) |
main
element<main>...</main>
nav
element<nav>...</nav>
ol
element<ol>
<li>Do this</li>
<li>Do that</li>
<li>Do something else</li>
</ol>
h1
element<h1>...</h1>
checked
attribute<input type="checkbox" checked>
checked
attributebutton
element<button>Play</button>
button
elementdiv
and span
elements as building blocks<div class="toolbar">
<span class="button">Bold</span><span class="button">Italic</span>...
</div>
Attributes that polyfill missing role, name, and state information for screen readers
role
attribute70+ roles, including:
aria-
attributes45+ states and properties, including:
aria-invalid
, aria-required
aria-pressed
, aria-expanded
aria-controls
, aria-owns
span
element<span id="button">Play</span>
role
attribute<span id="button" role="button">Play</span>
tabindex
attribute<span id="button" role="button" tabindex="0">Play</span>
<span id="button" role="button" tabindex="0">Play</span>
var button = document.getElementById('button');
button.addEventListener('click', doSomething, false);
button.addEventListener('keydown', function(event) {
if (event.keyCode == 13 || event.keyCode ==32) {
doSomething();
}
});
aria-pressed
attribute<span id="button" role="button" tabindex="0" aria-pressed="false">Play</span>
var button = document.getElementById('button');
function doSomething(event) {
if (button.getAttribute('aria-pressed') == 'false') {
button.setAttribute('aria-pressed', 'true');
}
else {
button.setAttribute('aria-pressed', 'false');
}
}
span[aria-pressed="true"] {
color: #fff;
padding: 11px 12px 9px 16px;
text-shadow: 0 -1px 0 #444, 0 0 5px #ffd, 0 0 8px #fff;
box-shadow: 0 1px 0 #666, 0 2px 0 #444, 0 2px 2px rgba(0,0,0,0.9);
}
aria-pressed
attributebutton
element<button id="button" aria-pressed="false">Play</button>
class tButton extends HTMLElement {
constructor () {
super();
var shadow = this.attachShadow({ mode: 'open' });
// Additional code
shadow.appendChild(button);
}
}
customElements.define('toggle-button', tButton);
button
elementconstructor () {
...
var button = document.createElement('button');
var text = this.innerHTML;
button.classList.add('toggle-button');
button.textContent = text;
...
}
constructor () {
...
function toggle(event) {
if (button.getAttribute('aria-pressed') == 'false') {
button.setAttribute('aria-pressed', 'true');
}
else {
button.setAttribute('aria-pressed', 'false');
}
}
button.addEventListener('click', toggle, false);
...
}
toggle-button
element<toggle-button>Play</toggle-button>
toggle-button
element<toggle-button aria-pressed="false">Play</toggle-button>
An experimental JavaScript accessibility API:
github.com/WICG/aom
Instead of:
button.setAttribute('role', 'button');
button.setAttribute('aria-pressed', 'false');
It would be:
button.role = 'button';
button.ariaPressed = 'false';
Authors will be able to:
ElementDefinitionOptions
objectElementInternals
objectAuthors will be able to respond to new types of input event, including:
actionIncrement
and actionDecrement
actionDismiss
actionScrollpageUp
and actionScrollPageDown
Will allow authors to create virtual accessibility tree nodes that do not map to the DOM
Will allow authors to:
Of the past, present, and future
Léonie Watson, TetraLogical