Upload
others
View
4
Download
0
Embed Size (px)
Citation preview
© 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 [email protected]
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