Op de #fronteers meetup van 23 juni 2011 vertelde ik een uurtje over de typische valkuilen in verband met keyboard accessibility. Wat loopt er zoals mis en wat doe je eraan?
3. Over Mij
★ Ik ben Roel
★ AnySurfer
★ Ik maak websites (in ruil voor geld)
sinds 2000. Freelance sinds 2003.
vrijdag 24 juni 2011
4. keyboard accessibility
★ Een fundamenteel onderdeel van een
toegankelijke site
WCAG Guideline 2.1:
“Keyboard Accessible: Make all functionality available from a keyboard”
★ Voor bezoekers met een motorische of
visuele handicap, muishaters, mobiele (!)
surfers en power users
★ Het lijkt een no-brainer, maar toch gaat het
vaak fout
vrijdag 24 juni 2011
5. Hoe voorkomen?
MUIS AAN DE KANT
eN TEST HET ZELF!
vrijdag 24 juni 2011
12. /* http://meyerweb.com/eric/tools/css/reset/
v2.0b1 | 201101
NOTE: WORK IN PROGRESS
USE WITH CAUTION AND TEST WITH ABANDON */
/* remember to define visible focus styles!
:focus {
! outline: ?????;
} */
vrijdag 24 juni 2011
13. Twee soorten mensen
★ Mensen die reset.css in al hun projecten
gebruiken en zich niet bewust zijn van het
probleem
★ Mensen die een afkeer hebben van de
‘dotted outline’ en doelbewust geen focus-
stijlen gebruiken
vrijdag 24 juni 2011
25. onthoud
★ Stijl je je :hover? Stijl dan ook je :focus
★ Wees creatief, maar vertrouw niet enkel op kleur
★ Vergeet gelinkte afbeeldingen niet!
★ Vertrouw geen forum posts uit 2003. Weet welke code je
gebruikt (reset.css, grid frameworks en boilerplates)
vrijdag 24 juni 2011
27. hoe werkt het ook alweer?
★ Eerst worden alle elementen mét tabindex
overlopen (oplopend: 1 → 32767)
★ Daarna worden alle elementen zonder
tabindex overlopen.
vrijdag 24 juni 2011
29. Home | Inschrijven | Over ons | Contact
Inschrijven
Uw gegevens Gegevens van uw partner
Naam Naam
Voornaam Voornaam
✔ Vegetarisch? ✔ Vegetarisch?
Verstuur
vrijdag 24 juni 2011
31. Home | Inschrijven | Over ons | Contact
Inschrijven
Uw gegevens Gegevens van uw partner
Naam tabindex="1"
Naam tabindex="4"
Voornaam tabindex="2"
Voornaam tabindex="5"
tabindex="3" tabindex="6"
✔ Vegetarisch? ✔ Vegetarisch?
Verstuur
vrijdag 24 juni 2011
32. wanneer nuttig?
★ Als je broncode logisch is opgebouwd, is een
tabindex bijna altijd overbodig.
★ Nuttig voor
★ Legacy code (tabellen)
★ ‘Content first’ of navigatieblokken
samenvoegen zonder de broncode
overhoop te hoeven gooien
vrijdag 24 juni 2011
33. tabindex
‘GEHeime’ wapens
vrijdag 24 juni 2011
34. tabindex="-1"
★ Voorkom dat een link of formulierelement
gefocust kan worden
★ element.focus() blijft gewoon werken
★ In combinatie met JavaScript: een handig
hulpmiddel voor het bouwen van UI
widgets met ARIA-ondersteuning
★ Ook handig om dubbele links te filteren
vrijdag 24 juni 2011
37. <a href="/monopoly">
<h2>
Zet Tongeren op het nieuwste spelbord
van Monopoly
</h2>
<figure>
<img src="monopoly.png" alt="Monopoly" />
<figcaption>Spelbord</figcaption>
</figure>
<p>
Tongeren komt in aanmerking om een plaats te
veroveren op het spelbord van de nieuwste
editie van Monopoly België.
</p>
<p class="more">Lees meer…</p>
</a>
vrijdag 24 juni 2011
38. linktekst = optelsom van alle tekst (en alt-
attributen tussen <a> en </a>
“Zet Tongeren op het nieuwste spelbord van Monopoly Monopoly Spelbord
Tongeren komt in aanmerking om een plaats te veroveren op het spelbord van de
nieuwste editie van Monopoly België. Lees meer”
vrijdag 24 juni 2011
39. <a href="/monopoly">
<h2>
Zet Tongeren op het nieuwste spelbord
van Monopoly
</h2>
<figure>
<img src="monopoly.png" alt="Monopoly" />
<figcaption>Spelbord</figcaption>
</figure>
<p>
Tongeren komt in aanmerking om een plaats te
veroveren op het <a href=”/spelbord”>spelbord</a>
van de nieuwste editie van Monopoly België.
</p>
<p class="more">Lees meer…</p>
</a>
vrijdag 24 juni 2011
42. Jaws 12
Internet Explorer 8 Firefox 4
vrijdag 24 juni 2011
43. DUS, BLOCK LEVEL <a>
★ Lange (verwarrende) links in linklijst van
Jaws, NVDA en VoiceOver.
★ Nested links → ‘DOM Vomit’ → verwart
screenreaders én je eigen scripts
★ Mogelijk alternatief: CSS (truc met
position: absolute, z-index en
overlappende transparante padding)
★ Gevolgen voor je SEO?
vrijdag 24 juni 2011
44. tabindex="0"
★ Geef alles focus: headings, tabelcellen, afbeeldingen etc.
zonder de tabvolgorde te beïnvloeden.
★ Nuttig om pagina-onderdelen te kunnen bereiken waar
een actie aan vasthangt en die niet standaard bereikbaar
zijn.
★ Voor ‘gewone’ links, gebruik je uiteraard <a href=”...”>
★ Ook gebruiken als je <span role="button"> gebruikt (!)
★ Addertje onder het gras: kunnen focussen betekent niet
noodzakelijk kunnen activeren
vrijdag 24 juni 2011
45. bereiken != activeren
★ Dat je op Enter kan klikken om op een link
te klikken of op spatie om een checkbox
aan te vinken, is een browser feature
★ Geef je een tabindex=”0” aan een *ander*
element (div, span), dan wordt het *jouw*
verantwoordelijkheid
★ KeyUp event 13 (Enter) is je vriend
vrijdag 24 juni 2011
49. wat is WAI-ARIA?
★ Web Acessibility Initiative - Accessible Rich
Internet Applications
★ Sinds 18 januari: W3C Candidate
Recommendation
★ Een set afspraken (classNames) om de rol, de
status en de eigenschappen van custom UI
widgets kenbaar te maken aan AT
★ Een extra laag je semantiek
(zoals microformats)
vrijdag 24 juni 2011
51. In de praktijk
★ Dezelfde <ul> kan een lijst met tabbladen,
een tree view of zelfs een volume slider
zijn. Met de juiste role en state kondigt
een screenreader de juiste zaken aan.
★ Het enige wat je screenreader doet, is
switchen naar Application mode.
vrijdag 24 juni 2011
52. BROWSE-modus
★ Je surft met een ‘onzichtbare cursor’ op een virtuele,
vereenvoudigde kopie van het DOM
★ Alle toetsaanslagen gaan naar de screenreader
★ h = volgende heading
★ u = volgende niet-bezochte link
★ v = volgende bezochte link
★ → = volgende letter (of woord)
★ ↓ = volgende ‘lijn’ (meestal DOM-node)
★ etc.
vrijdag 24 juni 2011
53. Applicatie-modus
★ Ook wel ‘Forms mode’ of ‘Focus mode’ genoemd
★ Toetsaanslagen gaan gewoon naar de browser, maar er is
wel audio- en braille-feedback.
★ De screenreader beslist zelf wanneer er geschakeld moet
worden tussen browse- en applicatiemodus. Bvb.:
★ Als je in een formulierveld terecht komt
★ Als je in een ARIA-enabled widget terechtkomt
★ Ah ja, want anders worden je keyUp() events niet
gedetecteerd en kan je geen letter h of l intikken in een
tekstveld etc.
vrijdag 24 juni 2011
55. <div id="tabs">
<ul class="tabsList">
<li id="tab-first" class="current">Eerste Tab</li>
<li id="tab-second">Tweede Tab</li>
<li id="tab-third">Derde Tab</li>
</ul>
<div class="tabPanel" style="display: block;">
<h1>Dit is de titel van het eerste tabblad</h1>
<p>…</p>
</div>
<div class="tabPanel" style="display: block;">
<h1>Dit is de titel van het tweede tabblad</h1>
<p>…</p>
</div>
<div class="tabPanel" style="display: block;">
<h1>Dit is de titel van het derder tabblad</h1>
<p>…</p>
</div>
</div>
vrijdag 24 juni 2011
56. <div id="tabs">
<ul class="tabsList" role="tablist">
<li id="tab-first" role="tab" aria-selected="true” class="current">Eerste
Tab</li>
<li id="tab-second" role="tab" aria-selected="false">Tweede Tab</li>
<li id="tab-third" role="tab" aria-selected="false">Derde Tab</li>
</ul>
<div class="tabPanel" role="tabpanel" aria-hidden="false" style="display:
block;" aria-labelledby="tab-first">
<h1>Dit is de titel van het eerste tabblad</h1>
<p>…</p>
</div>
<div class="tabPanel" role="tabpanel" aria-hidden="false" style="display:
none;" aria-labelledby="tab-second">
<h1>Dit is de titel van het tweede tabblad</h1>
<p>…</p>
</div>
<div class="tabPanel" role="tabpanel" aria-hidden="false" style="display:
none;" aria-labelledby="tab-third">
<h1>Dit is de titel van het derder tabblad</h1>
<p>…</p>
</div>
</div>
vrijdag 24 juni 2011
57. <div id="tabs">
<ul class="tabsList" role="tablist">
<li id="tab-first" role="tab" aria-selected="true" tabindex="0”
class="current">Eerste Tab</li>
<li id="tab-second" role="tab" aria-selected="false" tabindex="-1">Tweede
Tab</li>
<li id="tab-third" role="tab" aria-selected="false" tabindex="-1">Derde Tab</
li>
</ul>
<div class="tabPanel" role="tabpanel" aria-hidden="false" style="display:
block;" aria-labelledby="tab-first">
<h1>Dit is de titel van het eerste tabblad</h1>
<p>…</p>
</div>
<div class="tabPanel" role="tabpanel" aria-hidden="false" style="display:
none;" aria-labelledby="tab-second">
<h1>Dit is de titel van het tweede tabblad</h1>
<p>…</p>
</div>
<div class="tabPanel" role="tabpanel" aria-hidden="false" style="display:
none;" aria-labelledby="tab-third">
<h1>Dit is de titel van het derder tabblad</h1>
<p>…</p>
</div>
</div>
vrijdag 24 juni 2011
59. DUS
★ ARIA is geen magische oplossing
★ Je moet nog steeds zelf je keyUp() events
scripten (maar dat deed je sowieso al voor keyboard
users *zonder* screenreader!)
★ ARIA helpt screenreaders alleen door:
★ naar applicatiemodus te switchen
★ Nuttige semantische info te
communiceren aan de gebruiker
vrijdag 24 juni 2011
61. het probleem
★ In IE (<object>) en FF 4 (<embed>) kan je
wel *in* een Flash-object tabben
★ In andere browsers moet je op het object
klikken (met de muis!) voor je er met het
toetsenbord in kan navigeren
★ Sowieso beland je in een eindeloze loop
*binnen* het Flash-object (als deze
hotspots bevat tenminste)
vrijdag 24 juni 2011
62. 1
7
8 9
Text
2
3
4
5
6
10
vrijdag 24 juni 2011
63. workaround
★ Geef het Flash-object een tabindex="0"
en plaats een verborgen link (met een id)
net boven en onder het Flash-object
★ Gebruik SWFFocus.as (ActionScript class)
in je FLA-project
★ Die detecteert het einde van een
tabcyclus en voert een een stukje
JavaScript (focus()) uit op de webpagina
vrijdag 24 juni 2011
64. SWFFocus.as
★ Meer info en download: http://www.w3.org/
TR/WCAG-TECHS/FLASH17.html
★ Probleem: het werkt enkel met je eigen
Flash movies
★ Het is een hack
vrijdag 24 juni 2011
67. Mogelijkheid 1
★ Voeg <button>’s toe onder je filmpje
★ Gebruik de YouTube of DailyMotion API
voor play, pause, rewind en om het volume
te regelen.
★ Stijl de <button>’s en positioneer ze
netjes bovenop de Flash controls (gebruik
een wrapper <div> als positioning
context)
vrijdag 24 juni 2011
69. mogelijkheid 2
★ JWPlayer met HTML-knoppen
http://examples.anysurfer.be/
opleiding_video/
dragon_demo_accessible_JW5_JWembedd
er_yt.html
vrijdag 24 juni 2011
70. HTML 5 video?
★ Native controls zijn in alle browsers
behoorlijk toegankelijk
★ … behalve in Safari 5 :( Kwestie van tijd
★ Maar! Je kan de knoppen wel scripten
natuurlijk :)
★ DOEN!
vrijdag 24 juni 2011
73. <p class="skiplink"><a href="#inhoud">Naar inhoud</a></p>
<nav>
<ul>
<li><a href="…">Lorem</a></li>
<li><a href="…">Ipsum</a></li>
<li><a href="…">Dolor</a></li>
</ul>
</nav>
<section id="content">
<h1>Ah, de échte inhoud!</h1>
<p>Etiam porta sem malesuada magna mollis euismod.</p>
</section>
vrijdag 24 juni 2011
74. <p class="skiplink"><a href="#navigatie">Naar inhoud</a></p>
<section>
<h1>Content first? Beter voor je SEO?</h1>
<p>Etiam porta sem malesuada magna mollis euismod.</p>
</section>
<nav id="navigatie”>
<ul>
<li><a href="…">Lorem</a></li>
<li><a href="…">Ipsum</a></li>
<li><a href="…">Dolor</a></li>
</ul>
</nav>
vrijdag 24 juni 2011
75. de waarheid over skip links
★ Blinden hebben geen skip links nodig op
voowaarde dat je pagina netjes is
opgebouwd (koppen en lijsten)
★ Toch kunnen ze nuttig zijn! Maak ze dan
wel voor iedereen zichtbaar (voor mobiele
surfers, voor slechtzienden) of desnoods
zichtbaar bij :focus
vrijdag 24 juni 2011
85. Problemen
★ Geen afspraken of standaarden
★ Welke modifier keys?
★ Welke accesskeys voor welk soort links?
★ Vroeg of laat conflicteren ze
★ Met browser shortcuts
★ Met AT shortcuts
★ Met keyUp events
vrijdag 24 juni 2011
86. browser TOETSENCOMBINATIE CONFLICTEN
Alt Alt + F, Alt + E, Alt + V, Al + D, …
Shfit + Alt ✔
Ctrl Ctrl + C, Ctrl + V, …
Shift + Esc ✔
Ctrl + ⌥ ✔
vrijdag 24 juni 2011
87. meer problemen
★ In alle browsers, behalve Opera, wordt
voorrang gegeven aan accesskeys
★ Geen enkele browser, behalve Opera,
nodigt ze (native) aan.
★ Language issues
(Nederlands: Alt + e, Alt +w, Alt + b, Alt + f, Alt + x, Alt + h)
vrijdag 24 juni 2011
89. en keyup() events dan?
★ Maak ze optioneel (zoals Gmail het doet),
want ze kunnen ook conflicteren met AT
shortcuts. Neem ‘u’:
★ Gmail → Terug naar lijst met
conversaties
★ Jaws → Volgende niet-bezochte link
★ Uitzondering: Esc (voor lightboxes) en als
onderdeel van ARIA widgets
vrijdag 24 juni 2011
93. Dus
★ Neem niet klakkeloos scripts over (zeker
geen DreamWeaver-scripts)
★ Voorzie een bevestigingsknop bij een jump
menu.
★ Of gebruik geen jump menu’s
vrijdag 24 juni 2011
94. Don’t 4/4
Gewoon is al gek genoeg
vrijdag 24 juni 2011
98. DUS
★ Liever niet.
★ Als je klant blijft aandringen:
★ Met CSS (en/of JavaScript) kan je ieder
uitklapmenu toetsenbordvriendelijk
maken.
★ Maar is dat wel altijd nodig? Niet als het
submenu herhaald wordt op de
onderliggende pagina.
vrijdag 24 juni 2011
100. DUS
★ Fully keyboard accessible? Niet nodig!
★ Vermeld de datumnotatie (zoals dd/mm/jjjj)
★ Laat mensen een datum intikken (geen
disabled-attribuut op het tekstveld!)
★ Go native (HTML 5), maar zorg voor een
fallback
vrijdag 24 juni 2011
103. 1. :focus {outline: none} is evil
2. Screenreaders lezen je DOM, niet je HTML-bron
3. tabindex="0" en tabindex="-1" zijn je vrienden
4. Bereikbaar != activeerbaar (gebruik keyUp
event 13, 37, 38, 39 en 40)
5. WAI-ARIA lost niet al je problemen op
6. De enige écht toegankelijke video controls zijn
native of zitten buiten het Flash-object
7. Maak je skip links zichtbaar
8. Accesskeys zijn waardeloos
9. Gebruik je gezond verstand
10. Twijfels? Muis aan de kant en test het zelf
vrijdag 24 juni 2011