On Github marcysutton / accessible-javascript
Created by Marcy Sutton / @marcysutton Senior Front-End Engineer, Deque Systems
The Web is fundamentally designed to work for all people, whatever their hardware, software, language, culture, location, or physical or mental ability.
Note about aging population
http://webaim.org/articles/visual/lowvision
<a ng-href="#/wrong-trousers"></a> <button ng-click="start()"> <i class="icon"></i> </button>
<a ng-href="#/wrong-trousers">Techno-Trousers</a> <button ng-click="start()" aria-label="Start Day"> <i class="icon"></i> </button>
<a ng-href="#/wrong-trousers"></a> <button ng-click="start()"> <i class="icon"></i> </button>
<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] { 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
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
They come with native ARIA semantics as well as keyboard support.
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
Important for:
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
$('body').on('focusin', function() { console.log(document.activeElement); });JavaScript (jQuery)
http://pauljadam.com/bookmarklets/
npm install axe-core
describe('Form component', function () { document.getElementsByTagName('body')[0].insertAdjacentHTML('beforeend', '' + 'First name' + '' + ''); it('should have no accessibility errors', function (done) { var n = document.getElementById('username'); axe.a11yCheck(n, null, function (result) { expect(result.violations.length).toBe(0); done(); }); });
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
We can make it better.