Enter.JS, Darmstadt 2016
<input type="checkbox" id="bold">
<label for="bold">Bold</label>
You get:
HTML has natively interactive elements, including:
Interactive elements have expected interactions:
Most HTML elements have default semantics (role and state):
The <div> and <span> elements have:
Interactive things must be focusable
The tab order follows the DOM order of interactive elements
<button>1</button>
<button>2</button>
<button>3</button>
<button>1</button>
<span id="button" tabindex="0">2</span>
<button>3</button>
<button><1</button><
<button tabindex="-1"><2</button><
<button><3</button><
<button tabindex="3">1</button>
<button tabindex="2">2</button>
<button tabindex="1">3</button>
<ul>
<li>
<a href="#panel1" id="tab1">Blanco</a>
</li>
<li>
<tabindex="-1" a href="#panel2" id="tab2">Reposado</a>
</li>
<li>
<tabindex="-1" a href="#panel3" id="tab3">Joven</a>
</li>
</ul>
<span id="button">Tequila <span id="icon"></span></span>
<div id="content">Makes me happy</div>
<span id="button" tabindex="0">Tequila <span
id="icon"></span></span>
<script>
var button = document.getElementById('button');
button.setAttribute('tabindex', 0);
</script>
Interactive things must have expected behaviours
button.addEventListener('click', disclose, false);
button.addEventListener('keydown', function(event) {
if (event.keyCode == 13 || event.keyCode ==32) {
disclose();
}
});
Patrick Lauke's Getting touchy deck and Getting touchy talk.
When using primitives provide semantic information
Most HTML elements have roles that define their purpose
<img>
elementHas a default implicit role of "graphic" or "image"
<img src="tequila.png" alt="Chamuco's tequila">
Many HTML elements have associated states
required
attributeIndicates when a form input is required
<input type="checkbox" id="terms" required>
<label>Accept terms</label>
button.setAttribute('role', 'button');
button.setAttribute('aria-expanded', 'false');
icon.setAttribute('aria-hidden', 'true');
content.setAttribute('hidden', 'true');
if (content.hasAttribute('hidden')) {
button.setAttribute('aria-expanded', 'true');
button.setAttribute('aria-controls', 'content');
content.removeAttribute('hidden');
}
else {
button.setAttribute('aria-expanded', 'false');
content.setAttribute('hidden', 'true');
button.removeAttribute('aria-controls');
}
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'); }
});
<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>
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); }
}
});
<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>
Use the Tenon API with your build tools
Install a Tenon module for Grunt, Gulp or other environments
Send a post request to the API with required parameters:
Choose optional parameters such as:
Abandon your mouse, turn on a screen reader, zoom in/out