The old days
Flash and keyboard navigation
Screen readers and JavaScript
Page reloads for data interactions
Car phones in Miatas
The Web has evolved. Yay!
How do we code for accessibility now?
Browser inconsistencies w/ keyboard nav were a bitch
Flash accessibility required more effort. Poor access due to the nature of the "experience" (time-based, rapidly changing)
No fallback content == bad SEO. No live text in Flash even bad for Google (embedded in images or vectors)
What is accessibility?
The Web is fundamentally designed to work for all people, whatever their hardware, software, language, culture, location, or physical or mental ability.
Who are we talking about?
Blind & Low Vision
Color-Blind
Deaf & Hard of Hearing
Impaired Mobility
Cognitive/Learning
AND EVERYONE ELSE
A holistic approach to accessibility
makes the web better for everyone
Web pages are more than just visible
Semantic HTML markup
Headings
Landmark roles
Form labels
Image alt text
Visually hidden text
Web content is more than just audible
Video/audio captions
Transcripts
Audio descriptions
User interactions
User interaction: Apple password fail with shake + sound
But you came to hear about
Accessibility & JavaScript
Let’s talk about:
Keyboard events
Icon buttons
Focus management
Testing tools
Creating accessible actions
Empty buttons and links: bad!
<a ng-href="#/wrong-trousers"></a>
<button ng-click="start()">
<i class="icon"></i>
</button>
Unique and purposeful link text: good!
<a ng-href="#/wrong-trousers">Techno-Trousers</a>
<button ng-click="start()" aria-label="Start Day">
<i class="icon"></i>
</button>
Creating accessible actions Continued
Empty buttons and links: bad!
<a ng-href="#/wrong-trousers"></a>
<button ng-click="start()">
<i class="icon"></i>
</button>
Unique and purposeful link text: good!
<a ng-href="#/wrong-trousers">Techno-Trousers</a>
<button ng-click="start()">
<i class="icon" aria-hidden="true"></i>
<span class="icon-text">Start Day</span>
</button>
“Hidden” vs. “Offscreen” Styles
[hidden] {
display: none;
visibility: hidden;
}
CSS
.visuallyhidden {
border: 0;
clip: rect(0 0 0 0);
height: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
width: 1px;
}
CSS
WebAIM on invisible content
Keyboard navigation
Any element can receive focus with tabindex="0"
.
<div tabindex="0" class="nav-right"
role="button" aria-label="Next Slide">
</div>
HTML
$('.nav-right').on('click keydown', (event) => {
if (event.type === 'click' || event.keyCode === 13) {
navRightClicked();
}
});
jQuery
Use native buttons and links first.
They come with native ARIA semantics as well as keyboard support.
Skip Links
Useful for everyone. Make them visible on focus:
li.skip-link {
display: block;
margin: 0;
padding: 0;
position: absolute;
a {
display: block;
position: absolute;
left: -10000px;
top: 0;
width: 200px;
&:focus {
left: 0;
}
}
}
[tabindex="-1"]:focus {
outline: none;
}
SCSS
<ul>
<li>
<a href="#main">
Skip to Main content
</a>
</li>
</ul>
<main id="main" tabindex="-1">
</main>
HTML
http://codepen.io/marcysutton/pen/PZgbmm
Mega Menus (fixed)
Really hide inactive content
Make top level links into toggles
Close with escape key
Focus Management
Ensure focus is not dropped
Important for:
Client-side rendering
Deleting items in a UI
Interactive widgets
Focus management: a strategy
App.FocusManager = class FocusManager {
constructor() {
$('body').on('focusin', e => {
return this.oldFocus = $(e.target);
});
App.bind('rendered', e => {
if (!this.oldFocus) { return; }
if (this.oldFocus.data('focus-id')) { return this._focusById(); }
});
}
_focusById() {
let focusId = this.oldFocus.data('focus-id');
let newFocus = document.querySelector(`#${focusId}`);
if (newFocus) { return MyApp.focus(newFocus); }
}
};
JavaScript
Focus Management
Which item has focus? (debugging utility)
$('body').on('focusin', function() {
console.log(document.activeElement);
});
JavaScript (jQuery)
Testing for Accessibility
We can achieve digital equality by making accessibility part of our web development workflow.
aXe-core Open Source Accessibility Engine
Browser extensions
Unit test integration
Selenium Webdriver integration
aXe Chrome extension
Webdriver Integration
npm install axe-webdriverjs
var selenium = require('selenium-webdriver'),
AxeBuilder = require('axe-webdriverjs');
describe('Selenium-aXe Tutorial', function() {
beforeEach(function(done) {
this.driver = new selenium.Builder()
.forBrowser('firefox').build();
this.driver
.get('http://localhost:8000')
.then(function() { done(); });
});
afterEach(function() {
this.driver.quit();
});
it('Should have no accessibility violations', function(done) {
AxeBuilder(this.driver)
.analyze(function(results) {
expect(results.violations.length).toBe(0);
done();
})
});
});
https://github.com/marcysutton/axe-webdriverjs-demo
Should your mobile site be accessible?
It’s About User Experience.
We can make it better.
What else?
Feedback: hover/focus, updating widget instructions, external links, etc.
Tab order
Not trapping people in widgets they can’t get out of
Touch: make sure your events work
A whole other talk: How accessibility and automated testing are BFFs
Questions?