This presentation uses an out-of-the box HTML slideshow script which by itself is unaccessible. Keybindings exist to traverse forward and backward with arrow keys, but focus never shifts as the slides advance. The slides themselves are well structured, so you can use a read all command to listen to everything linearly. My good buddy Karl Groves also added a live region which should work well for screen readers that support live regions. As you traverse through the slides using arrow keys, the slide's content will be added to the live region. If all else fails, you can also access the slideshow content by turning off CSS and JavaScript.
With Billy Gregory, The Paciello Group
@TheBillyGregory
With Billy Gregory, The Paciello Group
@TheBillyGregory
Pig inspiration c/o Jared @ WebAIM's' "Accessibility Lipstick on a Usability Pig".
The background image is a pig wearing lipstick.
The background image is the word ARIA spelled out with bandaids. Too many developers use ARIA as an excuse for otherwise bad code that should instead just be written right.
The background image is Steve Rogers before he is injected with the Super Soldier serum in Captain America.
The background image is Captain America edited to read Captain ARIA.
If you can use a native HTML element [HTML5] or attribute with the semantics and behaviour you require already built in, instead of re-purposing an element and adding an ARIA role, state or property to make it accessible, then do so.
Know your role.
(Does not exist. Sorry.)
<nav role="navigation">
<ul>
</ul>
</nav>
<main role="main">
<h2 id="mainhead"> Home </h2>
</main>
Leonie Watson demonstrates how WAI-ARIA landmark roles help screen reader users understand the purpose of different areas of a web page, such as search, navigation or main content.
<span role="button" onclick="..."">
Click me!
</span>
<button onclick="..."">
Click me!
</button>
<span role="button" tabindex="0" onclick="...">
Click me!
</span>
The background is a movie poster for the film Liar Liar edited to say Aria Liar
role="button"
only changes how the AT recognizes the element(Aria is magic!)
(This one does exist.)
table
or ul
role=presentation
keep their semantics
<table role="presentation">
//required child elements inherit role=presentation
<tr>
<td>
//non required children do not inherit role=presentation
<h2> heading text </h2>
<p> textcontent in a paragraph </p>
</td>
</tr>
</table>
<div>
<table>
<tr>
<td>1</td>
<td>This is the first step</td>
</tr>
... //continued ...
</table>
<div>
<div role="group">
<table role="list">
<tr role="listitem">
<td>1</td>
<td>This is the first step</td>
</tr>
... //continued ...
</table>
<div>
<label for="date">Date:</label>
<input type="text" id="date">
<span>The correct format for the date is DD/MM/YYYY</span>
<label for="date">Date:</label>
<input type="text" id="date" aria-describedby="date-format">
<span id="date-format" tabindex="-1">The correct...</span>
NOTE: In IE if you use aria-labelledby
with multiple id
references or aria-describedby
with single or multiple id
references, the referenced elements must be what Microsoft terms as accessible HTML elements. The tabindex="-1"
was added to make this an "accessible element".
<label for="date">Date:*</label>
<input type="text" id="date" aria-describedby="date-format"
aria-required="true">
<span id="date-format" tabindex="-1">The correct...</span>
aria-invalid
to indicate a field is invalidValue | Description |
---|---|
false | No errors (default). |
grammar | A grammatical error is detected. |
spelling | A spelling error is detected. |
true | An invalid entry has been provided. |
<label for="surname">Surname * </label>
<input type="text"
aria-required="true"
aria-invalid="spelling"
id="surname"
name="surname">
<label for="surname">Surname * </label>
<input type="text"
aria-required="true"
aria-invalid="spelling"
aria-describedby="surnamecue"
id="surname"
name="surname">
<div id="surnamecue">
Your surname must start with a character.
</div>
<div tabindex="-1" id="errorSummary" role="group"
aria-labelledby="errorSummaryHeading">
<h2 id="errorSummaryHeading">Your information contains 2 errors</h2>
<ul>
<li>
<a href="#SecondaryPhone1">Phone Number 2: This field is required</a></li>
<li><a href="#AlertsText1">I can get information by (select at least one):
Please select at least one category</a></li>
</ul>
</div>
...
<label for="SecondaryPhone1">Phone Number 2:</label>
<input name="textfield" id="SecondaryPhone1" aria-invalid="true"
aria-required="true" type="text">
...
role="dialog"
role="alertdialog"
aria-labelledby
used to identify the element containing the accessible name for the dialog.aria-describedby
used to identify the information for a content dialog, and a description for an interactive dialog if required (note: required for a content dialog, and optional for an interactive dialog).
<div role="alertdialog" aria-labelledby="dlgtitle"
aria-describedby="instructions">
<h1 id="dlgtitle">Shutdown instructions</h1>
<ol id="instructions">
...
</ol>
<input type="button" value="OK">
</div>
<div role="dialog" aria-labelledby="dlgtitle">
<h1 id="dlgtitle">Sign up to Newsletter</h1>
<ol id="instructions">
<li>Enter email address</li>
<li>Press the 'Sign up' button</li>
</ol>
<label for="email">Email: </label>
<input type="text" id="email" name="email"
aria-describedby="instructions">
<input type="button" value="Sign up">
</div>
aria-live='polite'
aria-live='assertive'
alert
rolerole="log"
role="status"
role="alert"
role="marquee"
role="timer"
role="progressbar"
role="region"
<div id="result2" role="status"
aria-live="polite"> </div>
<button onclick="update2();">Update result 2</button>
<script>
var result2 = 0;
function update2() {
result2 = result2 + 1;
document.getElementById("result2").innerHTML=result2;
}
</script>
aria-atomic
true
or false
false
aria-relevant
aria-relevant="additions"
aria-relevant="removals"
aria-relevant="text"
aria-relevant="all"
aria-atomic="false"
aria-atomic="true"
<div role="status" aria-live="polite" aria-atomic="false"
>Score <span id="result5"> </span></div>
<button onclick="update5();">Update aria-atomic="false"</button>
<script>
var result5 = 0;
var result6 = 0;
function update5() {
result5 = result5 + 1;
document.getElementById("result5").innerHTML=result5;
}
function update6() {
result6 = result6 + 1;
document.getElementById("result6").innerHTML=result6;
}
</script>