New Zealand Government A11y for Developers
Workshop 2017

Jason Kiss
Senior Advisor

Department of Internal Affairs - Te Tari Taiwhenua

Assistive technologies

Keyboards

Close up of left hand on a Mac keyboard. Image source

Large print keyboards

Large print keyboard with yellow keys on black body. Image source

One-handed keyboards

Maltron one-handed keyboard for the right hand. Image source

Mice and trackballs

Large Kensington trackball. Image source
EZ Minicute vertical mouse. Image source

Headwands

Straight headwand strapped to a styrofoam head for display. Image source
Articulated headwand with head brace. Image source
Man with curved headwand typing at keyboard in front of monitor. Image source
Man with short headwand using onscreen keyboard on iPad. Image source

Mouthsticks

Mouthstick being used to type on iPad. Image source
Man using short mouthstick on special keyboard for mouthsticks. Image source
4 mouthsticks. Image source

Button switches

Red AMDI moon switch. Image source
Blue AMDI moon switch on articultated mounting brace. Image source

Sip and puff switches

Man using sip and puff switch with onscreen keyboard. Image source
Girl with sip and puff switch. Image source

Eye blink switch

Close up of fibre optic eye blink switch next to woman's eye. Image source

Proximity switch

Hand hovering over an Ablenet Candy Corn proximitiy switch. Image source

Switch scanning

Animated gif of scanning software selecting letter on SwithXS onscreen keyboard. Image source

Speech/voice recognition

Cortana logo. Image source
VoiceOver logo. Image source

Screen readers

JAWS for Windows banner image. Image source
Window-Eyes banner image. Image source
NVAccess logo. Image source
VoiceOver logo. Image source
Orca logo. Image source

Screen magnifiers

Screen magnifier in Mac OS. Image source
Screen magnifier in Windows 8. Image source

Braille displays

Braille Memo BM46 40 cell Braille display. Image source
Humanware Braille Notetaker. Image source

Affordable Braille display

Neil Jarvis from the RNZFB holding the new, affordable Orbit Braille display. Image source

How do browsers make content accessible to assistive technologies?

First there's the DOM

Tree diagram of the document object model. Image source

Next, accessibility APIs

Tree diagram of the document object model. Image source
text description

This image illustrates the relationship between user agents (e.g., browsers), accessibility APIs, and assistive technologies. It describes the 'contract' provided by the user agent to assistive technologies, which includes typical accessibility information found in the accessibility API for many of our accessible platforms for GUIs (role, state, selection, event notification, relationship information, and descriptions). The DOM, usually HTML, acts as the data model and view in a typical model-view-controller relationship, and JavaScript acts as the controller by manipulating the style and content of the displayed data. The user agent conveys relevant information to the operating system's accessibility API, which can be used by any assistive technologies, such as screen readers.

macOS

  • NSAccessibility protocol

Windows

  • MSAA
  • IAccessible2
  • UI Automation

Linux

  • ATK/AT-SPI

The Accessibility Tree

A tree of accessible objects

Diagram of a fictional accessibility tree with nodes showing different accessible objects. Image source

Accessible object

Your email address will never be shared.
 
<label for="email">Your email address:</label> 
<input type="text" id="email" aria-describedby="desc">
<div id="desc">Your email address will never be shared.</div>
					
  • Role → textbox
  • Accessible name → "Your email address:"
  • Accessible description → "Your email address will never be shared."
  • States and properties, e.g. focused, required, multi-line
  • Value, e.g. "web.standards@dia.govt.nz"

Inspecting the APIs

Windows

  • AViewer
  • Accessibility Probe
  • Inspect Objects (MS Windows SDK)

macOS

  • Accessibility Inspector (Xcode)

Gnome/Linux

  • Accerciser

Turn on Chrome Accessibility Internals

  1. chrome://accessibility
  2. Check all items under "Global accessibility mode:"
Screenshot of Chrome Accessibility Internals with all Global accessibility mode items checked.

Demo: Mac Accessibility Inspector

Types of pet

Do you like cats?

Chrome Dev Tools Accessibility Experiment

  1. chrome://flags
  2. Enable "Developer Tools experiments"
  3. Restart Chrome
  4. Developer Tools → Settings → Experiments → Accessibility Inspection
  5. Restart Developer Tools
  6. Inspect element → Check "Accessibility"

What do developers need to do?

Web Content Accessibility Guidelines (WCAG) 2.0

NZ Government
Web Accessibility Standard

WCAG 2.0 Level-AA compliance

Screenshot of NZ Government Web Accessibility Standard web page.

2014 Web Standards Self-Assessments

Top 10 accessibility issues

  1. WCAG 1.3.1 Info and relationships
  2. WCAG 1.1.1 Non-text content
  3. WCAG 1.4.3 Contrast (minimum)
  4. WCAG 4.1.2 Name, role, value
  5. WCAG 2.4 7 Focus visible
  6. WCAG 4.1.1 Parsing
  7. WCAG 1.4.1 Use of color
  8. WCAG 2.4.4 Link purpose (In context)
  9. WCAG 2.1.1 Keyboard
  10. WCAG 1.4.5 Images of text

2014 Web Standards Self-Assessments

Top 10 accessibility issues

  1. WCAG 1.3.1 Info and relationships
  2. WCAG 1.1.1 Non-text content
  3. WCAG 1.4.3 Contrast (minimum)
  4. WCAG 4.1.2 Name, role, value
  5. WCAG 2.4 7 Focus visible
  6. WCAG 4.1.1 Parsing
  7. WCAG 1.4.1 Use of color
  8. WCAG 2.4.4 Link purpose (In context)
  9. WCAG 2.1.1 Keyboard
  10. WCAG 1.4.5 Images of text

How to meet WCAG 2.0

Customisable quick reference to WCAG 2.0.

Screenshot of 'How to Meet WCAG 2.0' web page.

If you do one thing...

Make sure it works with keyboard only!

WCAG SC 1.3.1 Info and relationships

Information, structure, and relationships conveyed through presentation can be programmatically determined or are available in text.

Semantic structure

 
<h3>Types of pet</h3>
<ul>
    <li><a href="/cat/">cat</a></li>
    <li><a href="/dog/">dog</a></li>
    <li><a href="/kunekune/">kunekune</a></li>
</ul>
					

Types of pet

WCAG SC 4.1.2 Name, role, value

For all user interface components:

  • name and role can be programmatically determined
  • states, properties, and values can be programmatically set
  • notification of changes to these items is available to user agents, including assistive technologies

Roles, states, and properties

 
<form>
  <fieldset>
     <legend>Do you like cats?</legend>
     <input type="radio" name="cats" id="yes" value="yes" checked>
     <label for="yes">Yes</label>
     <input type="radio" name="cats" id="no" value="no">
     <label for="no">No</label>
  </fieldset>
  <input type="submit" value="Submit">
</form>
						
Do you like cats?

WCAG SC 2.1.1 Keyboard

All functionality of the content is operable through a keyboard interface.

Keyboard accessibility

Types of pet

Do you like cats?

Managing keyboard focus

  • tabindex="0"
    Adds an element to the Tab order at its position in the source order.
  • tabindex="-1"
    Removes an element from the Tab order. Makes non-focusable elements programmatically focusable.
  • tabindex="1+"
    (Avoid) Specifies an element's position following the default Tab order.

tabindex in action

Subheading (no tabindex)

Normal link to nowhere

Link with tabindex="-1"

Subheading (tabindex="-1")

span with tabindex="0"

Another normal link

Native vs. Custom Widgets

Example: Checkbox (1/3)

 
<input type="checkbox" id="dogs"...>
<label for="dogs">Dogs</label>

<div class="checkbox">Dogs</div>	

$('.checkbox').on('click', function() {
   $(this).toggleClass('checked');
});	

.checkbox {
  background: #222 url(../img/checkbox.png) 
    no-repeat 0 8px;
}
.checkbox.checked {
  background-image: 
    url(../img/checkbox-checked.png);
}
					
Dogs

No keyboard access.

No role or state information.

What to do?

Just use native checkboxes already!

But, if you must...

The solution: WAI-ARIA

Screenshot of WAI-ARIA 1.1 specification web page.

It's just attributes and values

  • roles use @role, e.g.
    role="navigation"
  • states and properties use @aria-*,
    e.g.
    aria-expanded="true"

It's part of the HTML5 specification.

Landmark roles

  • banner
  • complementary
  • contentinfo
  • form
  • main
  • navigation
  • region
  • search

hhttps://www.w3.org/TR/wai-aria-1.1/

Document structure roles

  • application
  • article
  • cell (new in ARIA 1.1)
  • columnheader
  • definition
  • directory
  • document
  • feed (new in ARIA 1.1)
  • figure (new in ARIA 1.1)
  • group
  • heading
  • img
  • list
  • listitem
  • math
  • none (new in ARIA 1.1)
  • note
  • presentation
  • region
  • row
  • rowgroup
  • rowheader
  • separator
  • table (new in ARIA 1.1)
  • term (new in ARIA 1.1)
  • toolbar

Standalone widget roles

  • alert
  • alertdialog
  • button
  • checkbox
  • dialog
  • gridcell
  • link
  • log
  • marquee
  • menuitem
  • menuitemcheckbox
  • menuitemradio
  • option
  • progressbar
  • radio
  • scrollbar
  • searchbox (new in ARIA 1.1)
  • slider
  • spinbutton
  • status
  • switch (new in ARIA 1.1)
  • tab
  • tabpanel
  • textbox
  • timer
  • tooltip
  • treeitem

Composite widget roles

  • combobox
  • grid
  • listbox
  • menu
  • menubar
  • radiogroup
  • tablist
  • tree
  • treegrid

https://www.w3.org/TR/wai-aria-1.1/#widget_roles

Live region roles

  • alert
  • log
  • marquee
  • status
  • timer

https://www.w3.org/TR/wai-aria-1.1/#live_region_roles

States and properties

Widget attributes

  • aria-autocomplete
  • aria-checked (state)
  • aria-disabled (state)
  • aria-errormessage (new in ARIA 1.1)
  • aria-expanded (state)
  • aria-haspopup
  • aria-hidden (state)
  • aria-invalid (state)
  • aria-keyshortcuts (new in ARIA 1.1)
  • aria-label
  • aria-level
  • aria-modal (new in ARIA 1.1)
  • aria-multiline
  • aria-multiselectable
  • aria-orientation
  • aria-placeholder (new in ARIA 1.1)
  • aria-pressed (state)
  • aria-roledescription (new in ARIA 1.1)
  • aria-readonly
  • aria-required
  • aria-selected (state)
  • aria-sort
  • aria-valuemax
  • aria-valuemin
  • aria-valuenow
  • aria-valuetext

Live region attributes

  • aria-atomic
  • aria-busy (state)
  • aria-live
  • aria-relevant

Relationship attributes

  • aria-activedescendant
  • aria-colcount (new in ARIA 1.1)
  • aria-colindex (new in ARIA 1.1)
  • aria-colspan (new in ARIA 1.1)
  • aria-current (new in ARIA 1.1)
  • aria-controls
  • aria-details (new in ARIA 1.1)
  • aria-describedby
  • aria-flowto
  • aria-labelledby
  • aria-owns
  • aria-posinset
  • aria-rowcount (new in ARIA 1.1)
  • aria-rowindex (new in ARIA 1.1)
  • aria-rowspan (new in ARIA 1.1)
  • aria-setsize

https://www.w3.org/TR/wai-aria-1.1/#state_prop_taxonomy

Native ARIA semantics

Landmarks

  • header → “banner” role, when its nearest ancestor sectioning element is body, and it's not a descendant of main
  • nav → “navigation” role
  • main → “main” role
  • aside → “complementary” role
  • footer → “contentinfo” role, when its nearest ancestor sectioning element is body, and it's not a descendant of main

Native ARIA semantics

Interactive components

  • a → “link” role
  • button → “button” role
  • input type="checkbox → “checkbox” role
  • input type="radio" → “radio” role

Overriding native HTML semantics

Valid

 
<a href="#">Link</a>

<a href="#" role="button">Button</a>
					

Invalid

 
<ul>
   <li role="button">list item button</li>
</ul>
						
  • list item button

Labels and descriptions

@aria-labelledby


<div id="label">Date</div>

<input type="text" aria-labelledby="label format">

<span id="format">(DD-MM-YYYY)</span>						
						
Date
(DD-MM-YYYY)

Labels and descriptions

@aria-label


<nav role="navigation" aria-label="Example main menu">
   <ul>
      …
   </ul>
</nav>
						

<button aria-label="Close">X</button>
						

Labels and descriptions

@aria-describedby


<label for="comment">Leave a comment</label>

<textarea id="comment" aria-describedby="notice"></textarea>

<p id="notice">Note: Your comment may be published.</p>
					

Note: Your comment may be published.

role="presentation|none"

Removes an element's default semantics.

 
<h3>Level 3 heading</h3>
					

Level 3 heading

 
<h3 role="presentation">Not a heading</h3>
					

role="presentation|none"

Removes an element's default semantics.

 
<table>
   <caption>Layout table</caption>
   <tr><td>Name:</td><td>Jonas Salk</td></tr>
   <tr><td>Discovery:</td><td>Polio vaccine</td></tr>
</table>
						
Layout table
Name: Jonas Salk
Discovery: Polio vaccine
 
<table role="none">
   <caption>Not a table</caption>
   <tr><td>Name:</td><td>Jonas Salk</td></tr>
   <tr><td>Discovery:</td><td>Polio vaccine</td></tr>
</table>
						
Not a table
Name: Jonas Salk
Discovery: Polio vaccine

Not on focusable elements

Don't do this!

It won't work anyway.

 
<a href="#" role="presentation">Still a link!</a>
						
Still a link!
 
<button role="none">Still a button!</a>
						

aria-hidden="true"

The element is not exposed to the a11y API, and so ATs.

Previous page

Previous page

Previous page

Previous page

Elements that are hidden (e.g. display:none;) are already not exposed.

Extreme caution when hiding visually rendered content!

Modal dialog demo

Live regions

  • aria-live="assertive|polite|off"
  • aria-atomic="true|false"
  • aria-relevant="additions|removals|text|all"

Live region demos

Example: Checkbox (1/3) Revisited

 
<input type="checkbox" id="dogs"...>
<label for="dogs">Dogs</label>

<div class="checkbox">Dogs</div>	

$('.checkbox').on('click', function() {
   $(this).toggleClass('checked');
});	

.checkbox {
  background: #222 url(../img/checkbox.png) 
    no-repeat 0 8px;
}
.checkbox.checked {
  background-image: 
    url(../img/checkbox-checked.png);
}
					
Dogs

No keyboard access.

No role or state information.

Example: Checkbox (2/3)

Add keyboard support

  1. add tabindex="0"
 
<div class="checkbox" tabindex="0">Dogs</div>	
  1. add handler for Space key

$('.checkbox').on('click', function() {
   $(this).toggleClass('checked');
});	

$('.checkbox').keydown(function(e) {
   if (e.which == 32) {
      $(this).click();
   }
});
Dogs

Still no role or state information.

Example: Checkbox (3/3)

Add role and state

  1. add role="checkbox" and @aria-checked
 
<div class="checkbox" tabindex="0" 
   role="checkbox" aria-checked="false">Dogs</div>	
  1. add toggle for @aria-checked

$('.checkbox').on('click', function() {
   if ($(this).attr('aria-checked') == 'false') {
      $(this).attr('aria-checked', 'true');
   } else {
      $(this).attr('aria-checked', 'false');
   }
});	

$('.checkbox').keydown(function(e) {
   if (e.which == 32) {
      $(this).click();
   }
});

Role and state provided.

A word of caution...

Using WAI-ARIA in HTML

First rule of ARIA use

Use native HTML elements and attributes as much as possible.

Second rule of ARIA use

Don't override native HTML semantics, unless absolutely necessary.

Background image source

What maps to what in the a11y APIs?

Due diligence

Black and white photo of small white dog digging with caption 'Dig Dig Dig'. Image source

Do the research, as you do…

ARIA demos

Other ARIA resources and demos

Thanks!

Questions?

Jason Kiss
Senior Advisor
Dept. of Internal Affairs
web.standards@dia.govt.nz
Twitter: @jkiss

Copyright

Creative Commons Attribution 4.0 International Licence
Crown copyright ©. Copyright material in this presentation is protected by copyright owned by the Department of Internal Affairs on behalf of the Crown. Unless indicated otherwise for specific items or collections of content (either below or within specific items or collections), this copyright material is licensed for re-use under a Creative Commons Attribution 4.0 International Licence. In essence, you are free to copy, distribute and adapt the material, as long as you attribute it to the Department of Internal Affairs and abide by the other licence terms. Please note that this licence does not apply to any logos, emblems and trade marks in the presentation or to the presentation's design elements. Where a photograph used in this presentation is accompanied by a link to its source, see the photograph's source for its copyright and licence terms.

The framework used to build this presentation, Reveal.js is protected by copyright owned by Hakim El Hattab and licensed for use under the MIT License.