Accessibility mechanics for web applications

Accessibility mechanics for web applications

Ember London meetup, April 2016

@LeonieWatson tink.uk

HTML

Role

Most HTML elements have roles that define their purpose

<img> element

Has a default implicit role of "graphic" or "image"


<img src="tequila.png" alt="Chamuco's tequila">

<main> element

Has a default implicit role of "main"


<main>
	<h1>Tequila</h1>
	...
</main>

<span> and <div> elements

Have semantically neutral default implicit roles


<span>Plain text</span>

Name

Some HTML elements can be given accessible names to identify them

<a> element

Accessible names can be the content of an HTML element


<a href="http://tink.uk">Tink UK</a>

<img> element

Accessible names can be assigned using HTML attributes


<img src="tequila.png" alt="Chamuco's tequila">

<label> element

Accessible names can be assigned using associated HTML elements


<label for="username">Username</label>
<input type="text" id="username">

State

Many HTML elements have associated states

required attribute

Indicates when a form input is required


<input type="checkbox" id="terms" required>
<label>Accept terms</label>

Keyboard focus

Interactive HTML elements come with keyboard support

<a> element

Can be focused on with the tab key, and activated with the enter key


<a href="http://tink.uk">Tink UK</a>

<button> element

Can be focused on with the tab key, and activated with the space or enter key


<button>Tequila</button>

DOM tree

DOM tree

Accessibility tree

Accessibility tree

Platform Accessibility APIs

Platform controls

Bold checkbox in Windows 10

Web control


<input type="checkbox" for="bold">
<label for="bold">Bold</label>

HTML Accessibility API Mappings (AAM)

The relationship between platform objects and web objects is documented in the HTML AAM

ARIA

Role

30+ roles including:

Name (and description)

Attributes for providing accessible names and descriptions:

State

9 states including:

Ember component


App.TequilaButtonComponent = Ember.Component.extend({
	tagName: 'tequila-button',
	nameBinding: 'tequila.name',
	attributeBindings: ['tabindex'],
	answer: false,
	label: function() { return "Is " + this.get('name') + " tequila good?"; }
					.property('name'),
	tabindex: 1,
	click: function(event) { alert('Yes'); }
});
	

Rendered DOM


<tequila-button tabindex="1" class="ember-view" id="ember260">
	<script type="text/x-placeholder" id="metamorph-2-start"></script>
	Is Reposado tequila good?
	<script type="text/x-placeholder" id="metamorph-2-end"></script>
</tequila-button>

Screen reader experience

Accessible Ember component


App.TequilaButtonComponent = Ember.Component.extend({
	tagName: 'tequila-button',
	nameBinding: 'tequila.name',
	attributeBindings: ['label:aria-label', 'tabindex'],
	answer: false,
	label: function() { return "Is " + this.get('name') + " tequila good?"; }
					.property('name'),
	tabindex: 0,
	ariaRole: 'button',
	click: function(event) { alert('Yes'); },
	keyDown: function(event) {
		if (event.keyCode == 13 || event.keyCode == 32) { this.click(event); }
	}
});
	

Rendered DOM


<tequila-button role="button" tabindex="0" aria-label="Is Reposado tequila good?"
 				class="ember-view" id="ember260">
	<script type="text/x-placeholder" id="metamorph-2-start"></script>
	Is Reposado tequila good?
	<script type="text/x-placeholder" id="metamorph-2-end"></script>
</tequila-button>

Screen reader experience

Ember a11y test suite

Use the Ember a11y test suite within the Ember framework.

Installation

Use Ember Cli to install Ember a11y testing as an add-on:


ember install ember-a11y-testing

Full test suite

Call the a11yTest method from inside an assertion:


test('Home page passes a11y tests', function(assert) {
  visit('/');

  andThen(function() {
    assert.ok(a11yTest());
  });
});

Run individual tests

Pass a configuration object to run specific tests:


test('Home page passes a11y tests', function(assert) {
  visit('/');

  andThen(function() {
    assert.ok(a11yTest({
      allActionsFocusable: false
    }));
  });
});

Tenon API

Use the Tenon API with your build tools

Installation

Install a Tenon module for Grunt, Gulp or other environments

Required parameters

Send a post request to the API with required parameters:

Optional parameters

Choose optional parameters such as:

Ember-axe

The Ember-axe plugin can be used to test accessibility within Ember

Test it yourself

Abandon your mouse, turn on a screen reader, zoom in/out

Thank you

Questions?