Presented at Midwest JS, August 14 2014. My talk on web accessibility for web developers. I cover basic techniques, introduce screen readers and ARIA, and go over testing. I also include extended examples around keyboard behavior and focus management as well as ARIA labels. The goal is to demystify accessibility so we can weave it in to applications today.
5. So how’d I get here?
A short story, starring WCAG 2.0 AA
!
!
!
6. Today
• Introduction to accessibility
• Techniques you can implement today
• Introduction to screen readers & ARIA
• Testing tips
7. Web Accessibility
• “When sites are correctly designed,
developed and edited, all users can have
equal access to information and
functionality” - Wikipedia
• “Able to be easily obtained or used; easily
understood or appreciated” - Oxford Dictionary
• Accessibility ~ Usability
• All people can use an application, and it
should be easy to use for all people;
8. Accessibility by the #’s
rough
1 - CDC Summary Health Statistics for U.S. Adults: National Health Interview Survey, 2011
http://1.usa.gov/M6tObC (under 65/over 65)
2 - Range worldwide prevalence of red-green color deficiency among men, 2012
http://1.usa.gov/M6tKsz
Group Population
Vision Problems 3-10%
Colorblindness 4-8%
Physical Functioning 8%
Cognitive Difficulty 6%
Hearing Difficulty 3-11%
Assistive Tools
• screen readers
• screen magnifiers
• keyboard-only
• braille display
• bumped font size
20. Visual Considerations
✓start with a good font size & high contrast
• Contrast Checker Tool - contrast-finder.tanaguru.com
• Chrome Plugin - http://bit.ly/1ljQvFF
• Accessible colour palette how-to http://bit.ly/1fnbmJp
✓don’t rely on colour alone
• add legends and texture or symbols
• all images have a meaningful alt attribute
• W3C How to write Alt Text http://bit.ly/1aKwIOg
• More from A List Apart http://bit.ly/1aKwRkI
21.
22. ✓ Every form field includes a real label
<label for="[INPUT ID]">
✓ Placeholders don’t count
✓ Labels can include help, required, error text
• Provide meaningful message and action on form
error
WebAIM Forms http://bit.ly/1aKw2bM
Harmful Placeholders http://bit.ly/1qNUTOM
WebAIM Validation http://bit.ly/1aKw6bB
Accessible Form Labeling http://bit.ly/1aKw83b
Forms
23. <label for="InputFirstName">
<span class="txt-label">First Name *</span>
<span class="txt-error">Required, please provide your first name</span>
</label>
<input type="text" id=“InputFirstName" required />
WebAIM Forms http://bit.ly/1aKw2bM
WebAIM Validation http://bit.ly/1aKw6bB
Accessible Form Labeling http://bit.ly/1aKw83b
Harmful Placeholders http://bit.ly/1qNUTOM
26. Keyboard Strategy
✓ obvious focus states (keep those outlines!)
• add tabindex=0 to non-focusable, clickable
elements
27. Keyboard Strategy
✓ obvious focus states (keep those outlines!)
✓ add tabindex=0 to non-focusable, clickable
elements
• add equivalents for :hover, hover() & click()
↳ :focus, focusin() & keydown()
$modalTrigger.attr('tabindex', '0');
$modalTrigger.on({
'click': handleTrigger,
'keydown': function (evt) {
var keyPressed = evt.keyCode;
if (keyPressed === app.keyCodes.ENTER || keyPressed === app.keyCodes.SPACE) {
handleTrigger();
28. Keyboard Strategy
✓ obvious focus states (keep those outlines!)
✓ add tabindex=0 to non-focusable, clickable
elements
✓ add equivalents for :hover, hover() & click()
↳ :focus, focusin() & keydown()
• HTML can get you there, FREE!
WebAIM http://bit.ly/M24Da2
Tabindex bit.ly/1xY7eCL
Keyboard Events http://bit.ly/M241Br
29. Wanted: Free Events!
<span class="btn toggle-trigger" tabindex="0">Click to Toggle</span>
!
<a href="#" class="btn toggle-trigger">Click to Toggle</a>
!
<button type="button" class="toggle-trigger">Click to Toggle</
button>
Use the button element http://bit.ly/1efaOO1
Links aren’t buttons http://bit.ly/1efaT4o
31. • Focus follows the user…
• opened modal window?
• scrolled viewport?
• transitioned to new view? focus()
Focus Management
focus()
focus()
32. • Focus follows the user…
• opened modal window?
• scrolled viewport?
• transitioned to new view?
• closed modal window? freakOut()
Focus Management
33. !
$modalTrigger.on('click', function(e){
var $modal,
modalTrigger = e.currentTarget;
!
// modal logic here
!
// save trigger elem so on modalClose it gets focus
$modal.data('trigger', modalTrigger);
});
!
handleModalClose = function() {
var newFocusElem = $modal.data('trigger');
!
// focus returns to the element that triggered the modal
$(newFocusElem).focus();
!
// remove the trigger, might be different next time
$modal.removeData('trigger');
};
http://codepen.io/mpiotrowicz/full/Juocl/
34. Have an exit strategy
mousetrap
Photograph by Sheba_Also licensed under Creative Commons
40. • Do your main content areas have headings?
• Are they descriptive?
• Do they follow a hierarchy? (h1 >> h6)
Headings
Document Outline http://bit.ly/1ef9ScA The Section Element http://bit.ly/1ef9TNN
Accessible Headings http://bit.ly/1ef9QBr Using Sections http://bit.ly/1ef9Ykx
H1 Blog
H2 Recent Articles
H3 Article Title
H3 Article Title
H3 Article Title
H2 About Me
H3 Contact Me
H3 Footer Title
• Main way screen reader users navigate
41. • img with empty alt attribute alt=""
SR’s ignore...
• :before content, :after content* (sort of)
• display: none;
• visibility: hidden;
* in most cases, so assume it won’t be announced
Accessible Icon Fonts http://bit.ly/1efabUP
.icon-star:before {
content: “★”;
}
• keep in mind for icons and icon fonts!
• or just use SVG
45. • Applied directly to HTML
!
• Does not affect styles or
non-SR behaviour
• Roles, states & properties
• Semantic information and better
interactions for screen readers
ARIA
• Part of HTML5 spec
HTML5 Spec (W3C) http://bit.ly/1aKxXx5
ARIA Spec (W3C) http://bit.ly/1aKya3f
46. Roles
• Create new semantic meaning for
elements via “role-” attribute
• Once set, they don’t change
<nav role="navigation">
!
<article role="article">
!
<div role="tablist">
!
<div role="combobox">
47. Landmark Roles
Define top-level page sections for easy navigation
!
•main
•banner
•navigation
•search
•complimentary
•contentinfo
•form
Role
48. Landmark Roles
Define top-level page sections for easy navigation
!
•main ........ <main>
•banner ........ <header>
•navigation ........ <nav>
•search ........ <form> (search form)
•complimentary ........ <aside>
•contentinfo ........ <footer>
•form
Role HTML 5
Using Landmarks http://bit.ly/1aKyuyQ
WebAIM Landmarks http://bit.ly/1aKytem
Support for HTML5 as landmarks http://bit.ly/LVR8YX
49. Include all content
in a landmark
Elements using
landmark roles
role="banner"
role="navigation"
role="main"
50. Widget Roles
Semantic meaning to your custom components
•tooltip
•slider
•dialog
•tab
•progressbar
•combobox
•menu
•alert
.. and many more!
http://www.w3.org/TR/wai-aria/roles#widget_roles
52. • Describe relationships between content &
between user interactions
• updated via JS on UI changes
• attributes start with “aria-” prefix
States & Properties
54. Content Relationships
• Semantically link labels to content or add
them when missing
• aria-labelledby
• aria-describedby
• aria-label
} text-element ID’s, comma-separated
string of label text
57. <label for="InputPhoneNumber">Phone Number</label>
<input aria-describedby="PhoneHelpText" id="InputPhoneNumber">
<span id="PhoneHelpText">
eg. 555-555-5555. We will use this number only in
case of emergency
</span>
Content Relationships
58. <label for="InputPhoneNumber">Phone Number</label>
<input aria-describedby="PhoneHelpText" aria-required="true"
id="InputPhoneNumber">
<span id="PhoneHelpText">
eg. 555-555-5555. We will use this number only in
case of emergency
</span>
Descriptions
59. <label for="InputPhoneNumber">Phone Number</label>
<input aria-describedby="PhoneHelpText" aria-required="true"
aria-invalid="true" id="InputPhoneNumber">
<span id="PhoneHelpText">
eg. 555-555-5555. We will use this number only in
case of emergency
</span>
Descriptions
60. <label for="InputPhoneNumber">Phone Number</label>
<input aria-describedby="PhoneHelpText" aria-required="true"
aria-invalid="true" id="InputPhoneNumber">
<span id="PhoneHelpText">
eg. 555-555-5555. We will use this number only in
case of emergency
</span>
Descriptions
aria-pressed
aria-selected
aria-checked
aria-disabled
aria-expanded
aria-controls
aria-haspopup
aria-valuemax
aria-valuemin
aria-multiselectable
aria-owns
aria-live
http://www.w3.org/TR/wai-aria/states_and_properties
61. It's just HTML!
.elem[aria-hidden = "false"] {
display: block;
}
!
.elem[aria-invalid ="true"] {
background: red;
}
!
.elem[aria-selected = "true"] {
border: green;
}
The more you know
62.
63. Putting it all together
• A11y Project Patterns http://a11yproject.com/patterns/
• Tab Example - http://codepen.io/mpiotrowicz/full/gocmu/
• Practical ARIA Examples http://bit.ly/1bhMqBg
• HTML5 & ARIA Design Patterns http://bit.ly/1bhMlNZ
• jQueryUI https://jqueryui.com/
• Bootstrap Accessibility Plugin (PayPal) http://bit.ly/1bhM8dy
• Accessible Web Components http://bit.ly/1iMwBiG
64. Using ARIA Wisely
• ARIA is a bridge, not a replacement.
• USE plain HTML if you can
• Not magic and makes no promises
• Events, focus management, keyboard support, and
meaningful structure is still up to you
• Only way to know for sure... TEST
65. ARIA Resources
Getting Started with ARIA
http://a11yproject.com/posts/getting-started-aria/
The WAI forward
http://www.smashingmagazine.com/2014/07/09/the-wai-forward/
W3C Intro
http://www.w3.org/TR/wai-aria-primer/
W3C Design Patterns
http://www.w3.org/TR/wai-aria-practices/
W3C Supporting Info for developers
http://www.w3.org/TR/aria-in-html/
WEBAIM Introduction
http://webaim.org/techniques/aria/
67. Automated Tools
• Accessibility Dev Tools (Chrome) http://bit.ly/1fW0W0A
• Web Dev Toolbar (Chrome & FF) http://bit.ly/1dA2JmY
• WebAIM WAVE (FF) http://wave.webaim.org/toolbar/
• Quail Project quailjs.org
• TenonIO - http://tenon.io/
68.
69. Manual Testing
• disable all images
• test with just a keyboard
• load it in a screen reader
• load it in another screen reader
10 Tips anyone can use http://bit.ly/1efaA9N
6 Tests anyone can do http://bit.ly/1efaC1c
Does your page make sense?
Is it usable ?
70. Unsolicited Advice
• Start small, there’s still a big impact
• Prioritize areas/pages
• main navigation?
• contact us form?
• homepage?
• Document as you go
76. More Resources
General
Accessibility Evaluation Quick Reference http://bit.ly/M6tgCF
The Accessibility Tree - http://bit.ly/1kzPmO6
Mozilla Dev Network ARIA http://mzl.la/M6u9ez
Screen Readers
WebAIM Screen Reader Testing http://bit.ly/M6sLIH
Videos of Screen Readers In Use http://bit.ly/M6sR39
How browsers interact with screen readers http://bit.ly/M6sUfi
NVDA resources
WebAIM NVDA http://bit.ly/M6sZj5
WebAIM NVDA Shortcuts http://bit.ly/M6t0n2
Using NVDA and FF to test pages http://bit.ly/M6t6Lu
Installing NVDA in a VM http://bit.ly/M6t8D4
VoiceOver resources
WebAIM VoiceOver http://bit.ly/M6tbyS
Apple VoiceOver User Guide http://bit.ly/M6tolE
Apple Developer Accessibility Guide http://bit.ly/M6ttpe
JAWS resources
WebAIM JAWS http://bit.ly/M6tw4D
WebAIM JAWS Shortcuts http://bit.ly/M6sBRM