Developing Accessible Web Apps
- how hard can it be?

Silvia Pfeiffer @silviapfeiffer, Alice Boxhall, Google
Linux.conf.au 2012
18th Jan 2012
Slide Template by HTML5 WOW
How many users are affected?

Types of assistive technology

  • Blind users
    with a screen reader that describes
    the page using synthesized speech
    or braille output.
  • Low-vision users
    who use large fonts or a screen magnifier.
  • Motor-impaired users
    who can’t use a mouse and may use
    a special keyboard or voice-control interface.
Screen reading on Linux: Orca
Screen reading in Google Chrome: ChromeVox

On Linux: also install the TTS Lois plugin to give ChromeVox a voice.

Overview
  1. How to make Web Apps accessible
  2. Assistive technology internals
  3. Latest developments

How to make Web Apps accessible

Example: Labelling - low-hanging fruit
<input type="text" id="user">
<input type="password" id="password">
<input type="checkbox" id="remember">
<br>
<span class="label_left">User Name</span>
<span class="label_middle">PIN</span>
<span class="label_right">Remember me</span>
Labelling - Made Accessible
<input type="text" id="user_correct">
<input type="password" id="password_correct">
<input type="checkbox" id="remember_correct">
<br>
<label for="user_correct" class="label_left"> User Name</label>
<label for="password_correct" class="label_middle"> PIN</label>
<label for="remember_correct" class="label_right">Remember me
</label>
Systematic Approach
  1. Use native elements
  2. Keyboard accessibility
  3. Screenreader accessibility
1. Use Native Elements

Generic divs or spans have no semantic meaning or functionality

<span onclick="">...
<div onclick="">...
  ⇒
<a href="">...
<button onclick="">...

What are the consequences?

  • Not focusable: can't be activated with the keyboard
  • No default key actions
  • Screen readers can't identify their role
  • NB: no adequate default styling
Custom button - Live Coding Example
<div>Click on this button:
<div class="custombutton"
onclick="alert('sent!')">Send</div>
</div>

change 'div' to 'button'

2. Keyboard accessibility

Unplug your mouse
   - use only [TAB] and [ENTER] keys.

Keep your eyes open for now :-)

  • Can you reach all interactive elements with [TAB]?
  • Can you activate interactive elements with [ENTER]?
  • DOM order - are the elements in the right tab order?
  • Focus management - after interaction: is the right element in focus?
Can you reach all interactive elements?
<div>Click on this link:
<span class="customlink"
onclick="alert('activated!')">Click</span>
</div>

add tabindex='0'

Can you activate interactive elements with [ENTER]?
<div>Click on this link:
<span tabindex="0" class="customlink"
onclick="alert('activated!')">Click</span>
</div>
<script>
function handlekey(event) {
 var target = event.target || event.srcElement;
 if (event.keyCode == 13) { target.onclick(); }
}
</script>

add onkeydown="handlekey(event);" handler

Are the elements in the right tab order?
<table class="customtabs">
  <tr>
    <td>Firstname: <input type="text" id="firstname"></td>
    <td>Address:  <input type="text" id="address"></td>
  </tr>
  <tr>
    <td>Lastname:  <input type="text" id="lastname"></td>
    <td>City:  <input type="text" id="city"></td>
  </tr>
</table>

add tabindex="10/20/30/40"

After interaction: is the focus right?
<button onclick="displayPopup('block');">Open Popup</button>
Something else: <input type="text" id="something">
<div id="custompopup" style="display:none;">
  <p>Press ok</p>
  <button id="popok" onclick="displayPopup('none');">OK</button>
</div>
<script>
function displayPopup(value) {
 document.getElementById("custompopup").style.display=value;
}
</script>

add document.getElementById("popok").focus();

Yay, we've reached keyboard accessibility!

 

Why is this important?

  • screenreader reaches controls individually
  • screenreader can activate controls
3. Screenreader Accessibility

Now you need to close your eyes for testing!

Semantics are often provided through visual cues

Would you like a cookie? 

What are the issues?

  • DOM order may need to be fixed
  • Role may need to get identified
  • States may need to be kept track of
  • Properties may need to be made explicit
  • Labels may need to be provided for elements
Example: bad DOM order
The plain in rain stays mainly in the Spain
    The <span>plain</span><span>in</span>
    <span>rain</span><span>stays mainly in
    the </span><span>Spain</span>
ARIA fixes roles, status and properties
  • ARIA = Accessible Rich Internet Applications, W3C standard.
  • ARIA attributes provide semantic information to screen readers that is normally conveyed visually
  • Note that using ARIA does not automatically implement the standard widget behavior - you'll still need to:
    • add focus management,
    • add keyboard navigation,
    • change aria attribute values in script.
ARIA Roles
  • Use the ARIA role attribute to indicate that a generic tag is playing the role of a standard widget like a button.
    <div tabindex="0" role="button">Menu button</div>
    
  • ARIA roles also indicate composite controls that do not have a native HTML equivalent.
    <div tabindex="-1" role="menu" >
      <div tabindex="0" role="menuitem">Paste</div>
      ...
    </div>
Example: adding ARIA role
<div tabindex="0">Menu</div>

add role="button"

ARIA States

Use different ARIA attributes to keep track of the state of a control.

  • aria-expanded keeps track of section hiding/showing.
    <div tabindex="0" role="button" aria-expanded="false">Justification</div>
    
  • aria-checked keeps track of checked items.
    <div role="menu" >
      <div tabindex="0" role="menuitem" aria-checked="true">Left</div>
      <div tabindex="0" role="menuitem" aria-checked="false">Center</div>
      <div tabindex="0" role="menuitem" aria-checked="false">Right</div>
    </div>
Example: adding ARIA states
<div id="ariamenu" role="menu">
 <div tabindex="0" role="menuitem" aria-checked="true">Left</div>
 <div tabindex="0" role="menuitem" aria-checked="false">Center</div>
 <div tabindex="0" role="menuitem" aria-checked="false">Right</div>
</div>
ARIA Properties

Use different ARIA properties to expose semantic information about a control.

  • Use aria-haspopup to indicate a popup button.
    <div tabindex="0" role="button" aria-haspopup="false">Normal Speed</div>
    
  • Use aria-activedescendant to keep track of the active contained item.
    <div tabindex="-1" role="menu" aria-activedescendant="id-Normal">
      <div id="id-Double" tabindex="0" role="menuitem">Double Speed</div>
      <div id="id-Normal" tabindex="0" role="menuitem">Normal Speed</div>
      <div id="id-Half" tabindex="0" role="menuitem">Half Speed</div>
    </div>
Example: adding ARIA properites
<div tabindex="0" role="button" aria-haspopup="false">Normal Speed</div>

change false to true

Are your controls and images labelled?
  • Use <label> on form elements.
    <label for="firstname">First name:</label>
    <input type="text" id="firstname"/>
  • Use alt on images.
    • Important images should have descriptive alt text.
      <img src="chart.png" alt="[description]">
    • Decorative images should have blank alt text.
      <img src="bullet35648.gif" alt="">
  • Use aria-label to provide text on other elements.
    <div tabindex="0" role="button" aria-label="Normal Speed">
Example: Pull-Up Menu with ARIA
<div title="Speed" class="button" id="button" tabindex="0" role="button" aria-haspopup ="true" aria-label="Normal Speed">
  <span>Normal</span>
</div>
<div class="menu" id="menu" tabindex="-1" role="menu" aria-activedescendant="id-Normal">
  <ul>
    <li id="id-Double" role="menuitem" data-value="Double">Double Speed</li>
    <li id="id-Normal" role="menuitem" data-value="Normal" aria-selected="true">Normal Speed</li>
    <li id="id-Half" role="menuitem" data-value="Half">Half Speed</li>
  </ul>
</div>
<script>
function changeButtonText(newText) {
  button.childNodes[1].innerHTML = newText;
  button.setAttribute('aria-label', newText + " Speed");
}
function setSelected(elem) {
  var curSelected = getSelected();
  items[curSelected].removeAttribute('aria-selected');
  elem.setAttribute('aria-selected', true);
  menu.setAttribute('aria-activedescendant', elem.id);
}
</script>
Recap

An Accessible Web App:

  • Uses native HTML tags instead of divs and spans.
  • Has the DOM structured in a sensible way.
  • Can be used entirely with the keyboard.
  • Implements intuitive focus management.
  • Labels all controls and images.
  • Includes ARIA for screen readers.
  • Has custom controls that follow this advice too!
Tools that can help you

ChromeVox

  • Built into Chrome OS
  • Available as an extension for Chrome Browser

ChromeShades

  • Accessibility testing tool for developers.
  • ChromeShades turns your pages into text only and formats them how a blind user would perceive them with a screen reader.
  • Install both from google-axs-chrome.googlecode.com

Some no-cost screen readers:

  • Orca (Linux, Open Source)
  • VoiceOver (Mac)
  • NVDA (Windows, Open Source)

Some JS libraries with accessibility support:

  • Dojo Toolkit
  • GWT
  • jQuery UI

Assistive technology internals

Implementing screenreader functionality into a Web browser

Two approaches:

  • Via a platform accessibility API interfacing with platform screenreaders
  • DIY
DIY

Implement your own screen-reader:

  • ChromeVox (Chrome on Linux, ChromeOS)
  • FireVox (FireFox; not updated since 2006)
Via a platform accessibility API
  • Most common
    • Chrome on Mac/Windows
    • Safari on Mac
    • FireFox on Linux/Mac/Windows
    • IE on Windows
    • Opera on Mac
Accessibility APIs

A programmatic view of the user interface elements and events of an application

Lots of different options for screenreaders

Your options will depend on your operating system

Accessibility APIs
API/s Screenreader/s Browser/s
ATK/AT-SPI Orca (Linux) Firefox
MSAA/IAccessible2 JAWS, NVDA (Windows) Firefox, Chrome
Microsoft UI Automation JAWS, NVDA (Windows) IE
NSAccessibility VoiceOver (OS X) Safari, Firefox, Chrome, Opera
ATK/AT-SPI

Developed by GNOME project

MSAA/IAccessible2
MSAA IAccessible2
  • Developed by Microsoft
  • Released 1997 as an add-on to Windows 95
  • Proprietary
  • Developed by IBM, building on MSAA
  • Released 2006
  • Open standard managed by Linux Foundation
NSAccessibility

Defines methods that OSX Cocoa applications have to implement to interface with screenreaders

WebKit cross-platform a11y
Accessibility Inspectors
Platform Tool
GNOME Accerciser
OSX Accessibility Inspector (built in)
Windows AccProbe (open source)
Current Work

ARIA and HTML5 integration

http://html5accessibility.com/

Video accessibility

http://html5videoguide.net/presentations/LCA_MM_Miniconf2012/

Google Chrome Accessibility

http://google-axs-chrome.googlecode.com

ChromeVox Discussion List

axs-chrome-discuss@google.com

Google's Accessibility Site

http://google.com/accessibility