improving the accessibility and usability of complex web … · 2016-07-08 · usability of complex...

Post on 08-Jul-2020

0 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

© 2014 Apple Inc. All rights reserved. Redistribution or public display not permitted without written permission from Apple.

#WWDC14

Improving the Accessibility and Usability of Complex Web Applications

Session 516 Jesse Bunch Productivity Engineering

Media

What You Will Learn

What You Will Learn

Accessibility fundamentals

What You Will Learn

Accessibility fundamentals

Latest research and statistics

What You Will Learn

Accessibility fundamentals

Latest research and statistics

Accessibility standards

What You Will Learn

Accessibility fundamentals

Latest research and statistics

Accessibility standards

ARIA and focus management

What You Will Learn

Accessibility fundamentals

Latest research and statistics

Accessibility standards

ARIA and focus management

Common issues and solutions

Accessibility

AccessibilitySupports real people with real needs by providing an alternate interaction model, like a keyboard or switch

Universal DesignDesign so thoughtful that it works for everyone

…ALIGNED PERFECTLY FOR AN INCREDIBLE SWING

Here’s Why

Visually impaired, worldwide285 Million

World Health Organization, 2013

Completely blind, worldwide40 Million

World Health Organization, 2013

Accessibility Standards

Web Content Accessibility GuidelinesWCAG

Basic Principles

Perceivable

Operable

Understandable

Robust

Perceivable

Perceivable

Operable

Understandable

Understandable

Understandable

Understandable

Understandable

Robust

Robust

Robust

Robust

Here’s How

Use Semantic Markup

Semantic Markup

Semantic Markup

Uses <div>

Semantic Markup

Uses <div> Uses semantic headings

Semantic Markup

<div style=“font-size: 18px;”> All About Widgets </div>

Semantic Markup

<div style=“font-size: 18px;”> All About Widgets </div>

Semantic Markup

<div style=“font-size: 18px;”> All About Widgets </div>

Semantic Markup

<div style=“font-size: 18px;”> All About Widgets </div>

<h1>All About Widgets</h1>

Semantic Markup

<div style=“font-size: 18px;”> All About Widgets </div>

<h1>All About Widgets</h1>

Semantic Markup

<div style=“font-size: 18px;”> All About Widgets </div>

<h1>All About Widgets</h1>

Use Standard Controls

ControlsCustom slider

0 100

ControlsCustom slider

<div class=“slider”> <div class=“left-label”> ... </div> <div class=“slider-handle”> ... </div> <div class=“right-label”> ... </div> </div>

0 100

ControlsCustom slider

<div class=“slider”> <div class=“left-label”> ... </div> <div class=“slider-handle”> ... </div> <div class=“right-label”> ... </div> </div>

// Mouseel.addEventListener(“mousedown”, handleMouseDown);el.addEventListener(“mousemove”, handleMouseMove);el.addEventListener(“mouseup”, handleMouseUp);

0 100

ControlsCustom slider

<div class=“slider”> <div class=“left-label”> ... </div> <div class=“slider-handle”> ... </div> <div class=“right-label”> ... </div> </div>

// Mouseel.addEventListener(“mousedown”, handleMouseDown);el.addEventListener(“mousemove”, handleMouseMove);el.addEventListener(“mouseup”, handleMouseUp);

// Touchel.addEventListener(“touchstart”, handleTouchStart);el.addEventListener(“touchmove”, handleTouchMove);el.addEventListener(“touchend”, handleTouchEnd);el.addEventListener(“touchleave”, handleTouchLeave);el.addEventListener(“touchcancel”, handleTouchCancel);

0 100

<div class=“slider”> <div class=“left-label”> ... </div> <div class=“slider-handle”> ... </div> <div class=“right-label”> ... </div> </div>

// Mouse el.addEventListener(“mousedown”, handleMouseDown); el.addEventListener(“mousemove”, handleMouseMove); el.addEventListener(“mouseup”, handleMouseUp); !

// Touch el.addEventListener(“touchstart”, handleTouchStart); el.addEventListener(“touchmove”, handleTouchMove); el.addEventListener(“touchend”, handleTouchEnd); el.addEventListener(“touchleave”, handleTouchLeave); el.addEventListener(“touchcancel”, handleTouchCancel);

<div class=“slider”> <div class=“left-label”> ... </div> <div class=“slider-handle”> ... </div> <div class=“right-label”> ... </div> </div>

// Mouse el.addEventListener(“mousedown”, handleMouseDown); el.addEventListener(“mousemove”, handleMouseMove); el.addEventListener(“mouseup”, handleMouseUp); !

// Touch el.addEventListener(“touchstart”, handleTouchStart); el.addEventListener(“touchmove”, handleTouchMove); el.addEventListener(“touchend”, handleTouchEnd); el.addEventListener(“touchleave”, handleTouchLeave); el.addEventListener(“touchcancel”, handleTouchCancel);

<div class=“slider”> <div class=“left-label”> ... </div> <div class=“slider-handle”> ... </div> <div class=“right-label”> ... </div> </div>

// Mouse el.addEventListener(“mousedown”, handleMouseDown); el.addEventListener(“mousemove”, handleMouseMove); el.addEventListener(“mouseup”, handleMouseUp); !

// Touch el.addEventListener(“touchstart”, handleTouchStart); el.addEventListener(“touchmove”, handleTouchMove); el.addEventListener(“touchend”, handleTouchEnd); el.addEventListener(“touchleave”, handleTouchLeave); el.addEventListener(“touchcancel”, handleTouchCancel);

// Keyboardel.addEventListener(“focus”, handleFocus);el.addEventListener(“blur”, handleBlur);el.addEventListener(“keydown”, handleKeyDown);

<div class=“slider”> <div class=“left-label”> ... </div> <div class=“slider-handle”> ... </div> <div class=“right-label”> ... </div> </div>

// Mouse el.addEventListener(“mousedown”, handleMouseDown); el.addEventListener(“mousemove”, handleMouseMove); el.addEventListener(“mouseup”, handleMouseUp); !

// Touch el.addEventListener(“touchstart”, handleTouchStart); el.addEventListener(“touchmove”, handleTouchMove); el.addEventListener(“touchend”, handleTouchEnd); el.addEventListener(“touchleave”, handleTouchLeave); el.addEventListener(“touchcancel”, handleTouchCancel);

// Keyboardel.addEventListener(“focus”, handleFocus);el.addEventListener(“blur”, handleBlur);el.addEventListener(“keydown”, handleKeyDown);

ControlsNative slider

ControlsNative slider

<input type=“range” min=“0” max=“100” value=“1”>

ControlsNative slider

<input type=“range” min=“0” max=“100” value=“1”>

Browser Handles• Mouse events

• Touch events

• Keyboard events

• Tracking state

• Style updates for focus and blur

• Notifying observers

• Accessibility

ControlsNative slider

<input type=“range” min=“0” max=“100” value=“1”>

Browser Handles• Mouse events

• Touch events

• Keyboard events

• Tracking state

• Style updates for focus and blur

• Notifying observers

• Accessibility

ControlsCustom slider

<div> <div class=“left-label”> ... </div> <div class=“slider-handle”> ... </div> <div class=“right-label”> ... </div> </div>

// Mouse el.addEventListener(“mousedown”, handleMouseDown); el.addEventListener(“mousemove”, handleMouseMove); el.addEventListener(“mouseup”, handleMouseUp); !

// Touch el.addEventListener(“touchstart”, handleTouchStart); el.addEventListener(“touchmove”, handleTouchMove); el.addEventListener(“touchend”, handleTouchEnd); el.addEventListener(“touchleave”, handleTouchLeave); el.addEventListener(“touchcancel”, handleTouchCancel);

<div> <div class=“left-label”> ... </div> <div class=“slider-handle”> ... </div> <div class=“right-label”> ... </div> </div>

ControlsCustom slider

// Mouse el.addEventListener(“mousedown”, handleMouseDown); el.addEventListener(“mousemove”, handleMouseMove); el.addEventListener(“mouseup”, handleMouseUp); !

// Touch el.addEventListener(“touchstart”, handleTouchStart); el.addEventListener(“touchmove”, handleTouchMove); el.addEventListener(“touchend”, handleTouchEnd); el.addEventListener(“touchleave”, handleTouchLeave); el.addEventListener(“touchcancel”, handleTouchCancel);

ARIAAccessible Rich Internet Applications

ARIACustom slider

<div> <div class=“left-label”> ... </div> <div class=“slider-handle”> ... </div> <div class=“right-label”> ... </div> </div>

// Mouse el.addEventListener(“mousedown”, handleMouseDown); el.addEventListener(“mousemove”, handleMouseMove); el.addEventListener(“mouseup”, handleMouseUp); !

// Touch el.addEventListener(“touchstart”, handleTouchStart); el.addEventListener(“touchmove”, handleTouchMove); el.addEventListener(“touchend”, handleTouchEnd); el.addEventListener(“touchleave”, handleTouchLeave); el.addEventListener(“touchcancel”, handleTouchCancel);

ARIACustom slider

<div role=“slider”> <div class=“left-label”> ... </div> <div class=“slider-handle”> ... </div> <div class=“right-label”> ... </div> </div>

// Mouse el.addEventListener(“mousedown”, handleMouseDown); el.addEventListener(“mousemove”, handleMouseMove); el.addEventListener(“mouseup”, handleMouseUp); !

// Touch el.addEventListener(“touchstart”, handleTouchStart); el.addEventListener(“touchmove”, handleTouchMove); el.addEventListener(“touchend”, handleTouchEnd); el.addEventListener(“touchleave”, handleTouchLeave); el.addEventListener(“touchcancel”, handleTouchCancel);

ARIACustom slider

<div role=“slider” aria-valuemin=“0” aria-valuemax=“100”> <div class=“left-label”> ... </div> <div class=“slider-handle”> ... </div> <div class=“right-label”> ... </div> </div>

// Mouse el.addEventListener(“mousedown”, handleMouseDown); el.addEventListener(“mousemove”, handleMouseMove); el.addEventListener(“mouseup”, handleMouseUp); !

// Touch el.addEventListener(“touchstart”, handleTouchStart); el.addEventListener(“touchmove”, handleTouchMove); el.addEventListener(“touchend”, handleTouchEnd); el.addEventListener(“touchleave”, handleTouchLeave); el.addEventListener(“touchcancel”, handleTouchCancel);

ARIACustom slider

<div role=“slider” aria-valuemin=“0” aria-valuemax=“100” aria-valuenow=“50”> <div class=“left-label”> ... </div> <div class=“slider-handle”> ... </div> <div class=“right-label”> ... </div> </div>

// Mouse el.addEventListener(“mousedown”, handleMouseDown); el.addEventListener(“mousemove”, handleMouseMove); el.addEventListener(“mouseup”, handleMouseUp); !

// Touch el.addEventListener(“touchstart”, handleTouchStart); el.addEventListener(“touchmove”, handleTouchMove); el.addEventListener(“touchend”, handleTouchEnd); el.addEventListener(“touchleave”, handleTouchLeave); el.addEventListener(“touchcancel”, handleTouchCancel);

ARIARetrofitting old content

ARIARetrofitting old content

<div style=“font-size: 18px”> All About Widgets </div>

ARIARetrofitting old content

<div style=“font-size: 18px” role=“heading” aria-level=“1”> All About Widgets </div>

ARIAImplicit roles

// Implicitly gets role=“heading” and aria-level=“1” <h1>All About Widgets</h1> !

ARIAImplicit roles

// Implicitly gets role=“heading” and aria-level=“1” <h1>All About Widgets</h1> !

// Effectively the same as a <div> tag <h1 role=“presentation”>All About Widgets</h1> !

Focus Management

Focus Managementtabindex

Focus Managementtabindex

tabindex=“0”Focusable with JavaScript, in default tab order

tabindex=“-1”Focusable with JavaScript, not in default tab order

No tabindexNot focusable with JavaScript, not in default tab order** Except for native controls and links

Focus Managementtabindex

tabindex=“0”Focusable with JavaScript, in default tab order

tabindex=“-1”Focusable with JavaScript, not in default tab order

No tabindexNot focusable with JavaScript, not in default tab order** Except for native controls and links

Focus Managementtabindex

tabindex=“0”Focusable with JavaScript, in default tab order

tabindex=“-1”Focusable with JavaScript, not in default tab order

No tabindexNot focusable with JavaScript, not in default tab order** Except for native controls and links

Focus Managementtabindex

tabindex=“0”Focusable with JavaScript, in default tab order

tabindex=“-1”Focusable with JavaScript, not in default tab order

No tabindexNot focusable with JavaScript, not in default tab order** Except for native controls and links

tabindex=“0”

tabindex=“0”

tabindex=“0”

tabindex=“0”

tabindex=“0”

tabindex=“0”

tabindex=“0”

tabindex=“0”

tabindex=“0”

tabindex=“0”

tabindex=“0”

tabindex=“-1”

tabindex=“-1”

tabindex=“-1”

tabindex=“-1”

tabindex=“-1”

tabindex=“-1”

tabindex=“-1”

tabindex=“-1”

tabindex=“-1”

tabindex=“0”

tabindex=“-1”

tabindex=“-1”

tabindex=“-1”

tabindex=“-1”

tabindex=“-1”

tabindex=“-1”

tabindex=“-1”

tabindex=“-1”

tabindex=“-1”

tabindex=“0”

tabindex=“-1”

tabindex=“-1”

tabindex=“-1”

tabindex=“-1”

tabindex=“-1”

tabindex=“-1”

tabindex=“-1”

tabindex=“-1”

tabindex=“-1”

tabindex=“-1”

tabindex=“0”

tabindex=“-1”

tabindex=“-1”

tabindex=“-1”

tabindex=“-1”

tabindex=“-1”

tabindex=“-1”

tabindex=“-1”

tabindex=“-1”

tabindex=“-1”

tabindex=“-1”

tabindex=“0”

tabindex=“-1”

tabindex=“-1”

tabindex=“-1”

tabindex=“-1”

tabindex=“-1”

tabindex=“-1”

tabindex=“-1”

tabindex=“-1”

tabindex=“-1”

tabindex=“0”

tabindex=“-1”

tabindex=“-1”

tabindex=“-1”

tabindex=“-1”

tabindex=“-1”

tabindex=“-1”

tabindex=“-1”

tabindex=“-1”

tabindex=“-1”

tabindex=“0”

tabindex=“-1”

tabindex=“-1”

tabindex=“-1”

tabindex=“-1”

tabindex=“-1”

tabindex=“-1”

tabindex=“-1”

Perceivable

Operable

Understandable

Robust

Demo

Summary

Summary

Perceivable, operable, understandable, robust

Summary

Perceivable, operable, understandable, robust

Use standard controls and semantic markup

Summary

Perceivable, operable, understandable, robust

Use standard controls and semantic markup

Use ARIA to fill the gaps

Summary

Perceivable, operable, understandable, robust

Use standard controls and semantic markup

Use ARIA to fill the gaps

Make sure controls are keyboard accessible

More Information

Jake Behrens App Frameworks Evangelist behrens@apple.com

Web Content Accessibility Guidelines http://www.w3.org/WAI/intro/wcag

ARIA Documentation http://www.w3.org/WAI/intro/aria

Combining Web Accessibility and Automation on iOS https://developer.apple.com/videos/wwdc/2011/

Apple Developer Forums http://devforums.apple.com

Related Sessions

• Accessibility on OS X Russian Hill Tuesday 2:00 PM

• Accessibility on iOS Russian Hill Tuesday 3:15 PM

• Web Inspector and Modern JavaScript Russian Hill Thursday 10:15 AM

top related