Romke van der Meulen

We zijn bij Vevida doorlopend bezig om de accessibility (toegankelijkheid) van onze webapps te verbeteren. Daarmee hopen we onze producten en diensten beschikbaar te maken voor een zo breed mogelijk publiek. In dit artikel wil ik jou als collega web-ontwikkelaar wat tips aanreiken zodat de accessibility van jouw websites direct bij het ontwikkelen al goed zit.

Verplaats je in de doelgroepen

Goede accessibility vereist een ruime blik en verschillende perspectieven. Een gebruiker met motorische beperkingen heeft misschien moeite met precies klikken. Dus je links en knoppen moeten ruim zijn en genoeg afstand hebben tot elkaar. Gebruikers met visuele beperkingen hebben misschien moeite met subtiele kleurverschillen. Dus de voor- en achtergrondkleuren in je ontwerp moeten voldoende contrast hebben. Een gebruiker met auditieve beperking kan enorm worden geholpen door ondertiteling op je videos en voor gebruikers met cognitieve beperkingen is het belangrijk dat de website duidelijk en consistent is.

Een hoop problemen kun je zelf makkelijk herkennen zolang je je maar in de doelgroep verplaatst. Ik raad iedereen aan het artikel “Stories of Web Users” van de W3C te lezen: dat kan je enorm helpen een beeld te vormen en met een nieuw perspectief naar je code te kijken.

Screenreaders

In dit artikel ga ik met name in op tips om jouw website goed geschikt te maken voor screenreaders. Dit vergt namelijk de meest technisch complexe oplossingen. Dat wil niet zeggen dat andere accessibility problemen niet belangrijk zijn, maar ze zijn vaak eerder in het ontwerpproces van belang.

Zoals ik in mijn eerdere artikel over accessibility al vertelde kom je een heel eind om jouw website geschikt te maken voor screenreaders als je je netjes aan de HTML-standaarden houdt. Semantische HTML kan de accessibility ook enorm helpen. Denk hierbij bijvoorbeeld aan koppen die qua niveau correct gestructureerd zijn, een opsomming die netjes in een <ul> staat in plaats van een serie <span>-elementen, of een serie radio inputs die als groep gelabeld zijn met een <fieldset> en een <legend>. En HTML5 landmark elementen zoals <nav>, <main> of <footer> kunnen gebruikers helpen makkelijker hun weg te vinden op de pagina.

ARIA

Maar alleen semantische HTML is nog niet genoeg. Vooral naarmate websites zich steeds meer als apps beginnen te gedragen. Waar HTML nog tekort schiet kun je gebruik maken van ARIA (Accessible Rich Internet Applications). Ik geef een paar voorbeelden:

aria-describedby

<label for="input-element">Kies een wachtwoord</label>
<input type="password" id="input-element"
    aria-describedby="wachtwoordeisen">

<p id="wachtwoordeisen">
  Gebruik tenminste acht tekens, waaronder een hoofdletter,
  een cijfer, en een symbool.
</p>

Gebruikers zonder visuele beperkingen zien in een oogopslag dat het invoerveld en de beschrijving bij elkaar horen. Een screenreader gaat echter een voor een de items bij langs. Gebruikers van een screenreader ontdekken in dit voorbeeld dus misschien de wachtwoordeisen pas nadat ze het veld al hebben ingevuld. aria-describedby en aria-labelledby helpen je om content die visueel gegroepeerd is ook in de DOM aan elkaar te linken. Hierdoor leest een screenreader wanneer het invoerveld gefocust is de gerelateerde wachtwoordeisen ook direct voor.

aria-hidden

<div>
  <span aria-hidden="true" class="doorgehaalde-prijs">€ 50</span>
  <span aria-hidden="true" class="nieuwe-prijs">€ 10</span>
  <span class="niet-visueel">van € 50 voor € 10</span>
</div>

Hartstikke mooi natuurlijk dat jouw webshop een afgeprijsd product laat spetteren door met styling een dikke rode streep door de oude prijs heen te zetten, maar screenreaders merken daar natuurlijk niets van. Een goeie oplossing in onze ervaring is om puur visuele informatie aan screenreaders apart aan te bieden in een frase of zin. Het aria-hiddenattribute zorgt ervoor dat de screenreader de visuele informatie negeert (en de prijzen dus niet twee keer voorleest). De niet-visueel class zorgt met styling ervoor dat deze tekst niet zichtbaar is en de prijzen dus niet twee keer worden getoond. Er zijn verschillende manieren hoe je de CSS voor niet-visueel kunt schrijven. Wij doen dit:

.niet-visueel {
  position: absolute;
  left: -10000px;
  top: auto;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

Waarom niet gewoon display:none? Screenreaders doen hun best om hun gebruikers dezelfde informatie te geven als wat andere gebruikers op het scherm zien. Daarom wordt verborgen content met opzet niet voorgelezen. Deze styling werkt daar omheen.

aria-busy

<button class="${bezigMetOpslaan ? 'loading' : ''}"
    aria-busy="${bezigMetOpslaan}">Opslaan</button>

Het kan even duren voordat de gegevens in een formulier opgeslagen zijn. In de tussentijd wil je natuurlijk wel aan je gebruikers duidelijk maken dat je hun klik hebt ontvangen en druk voor ze bezig bent. Dus je voegt een class toe die een spinner animatie bij de knop toont om aan te geven dat er een langdurige handeling bezig is. Maar als de gebruiker die animatie niet kan zien werkt het natuurlijk niet. Ook hier schiet ARIA te hulp. Zodra in de DOM aria-busy="true" staat, meldt de screenreader dat de knop “bezig” is.

(Hier is trouwens een interessant feitje over <button>: deze tag heeft een type attribute die standaard staat ingesteld op submit. Dus als je in een formulier meerdere <button>s hebt staan en je geeft geen van deze elementen een type="button" dan kunnen er vreemde dingen gebeuren. Bijvoorbeeld dat je in een formulierveld op Enter drukt en de eerste de beste knop in het formulier aangeklikt wordt in plaats van de “Opslaan” knop onderaan het formulier. Hier ben ik al een paar keer tegenaan gelopen.)

Nog meer ARIA

Veel accessibility problemen die we tegenkomen kunnen opgelost worden met deze ARIA attributes. Maar er zijn nog veel meer ARIA attributes die zaken die visueel duidelijk zijn ook kunnen uitleggen aan screenreaders, zoals aria-expanded en aria-live. Ik raad je aan de volledige lijst in de WAI-ARIA specificatie goed door te nemen.

Het probleem met focus

function naFrontendNavigatie() {
  var kop = document.querySelector("h1");
  kop.setAttribute("tabindex", "-1");
  kop.focus();
}

We zijn lang bezig geweest ons klantportaal MyVevida om te bouwen naar een single page app (zie “Hoe MyVevida een single page app werd“). Navigatie zonder een full page reload is enorm hip maar lastig voor screenreaders om te begrijpen. Om te zorgen dat gebruikers toch altijd weten waar ze zijn, zetten we na navigatie altijd de focus terug naar de paginakop. tabindex="-1" zorgt ervoor dat het element niet met toetsenbordnavigatie te bereiken is (het is tenslotte niet een interactief element), maar dat JavaScript wel de focus op dit element mag zetten. Zodra de kop wordt gefocust leest de screenreader de kop voor en is duidelijk dat de gebruiker op een nieuwe pagina is beland.

Goed focus management is een onderwerp op zich en misschien wel het lastigste probleem dat we zijn tegengekomen. In het algemeen is de stelregel voor ontwikkelaars dat je van de focus afblijft: dat is aan de gebruiker. Maar er zijn situaties waarin je er niet omheen kunt, met name als de context waar de focus stond verdwijnt. Dat kan bijvoorbeeld zijn omdat je naar een nieuwe pagina gaat of in een popup zat die gesloten wordt. In die gevallen is het aan de developer om de focus terug te zetten op een zinnige plek. Je wilt niet dat de focus helemaal teruggaat naar het begin van de pagina en de gebruiker zelf terug moet navigeren naar de context waar hij of zij mee bezig was. Dat zorgt voor een slechte gebruikerservaring. Ik heb helaas geen handige trucjes om te delen: dit is een moeilijk probleem en elke oplossing is uniek.

Testen

Natuurlijk wil je als developer wel kunnen checken of de HTML die je schrijft accessible en correct is. Er zijn enkele tools die jou kunnen helpen om fouten op te sporen. Zelf gebruik ik de WAVE Chrome plugin en de in Chrome ingebakken Lighthouse analyse tool.

Maar om zeker te weten dat jouw HTML goed werkt met screenreaders is er maar een manier: installeer zelf een screenreader en probeer het uit. Op Mac staat VoiceOver al voorgeïnstalleerd: je hoeft het alleen te activeren. Op Windows kun je de opensource NVDA screenreader gebruiken of je kunt een licentie op JAWS nemen. Voor Linux bestaat Orca, maar ik adviseer je een van de andere pakketten te gebruiken aangezien Orca zelden wordt gebruikt door mensen met een visuele beperking.

Tijd en moeite

Het schrijven van accessible HTML is een vaardigheid op zich, eentje die je jezelf met tijd en moeite eigen moet maken. In mijn ervaring is het die moeite zeker waard, al was het alleen maar omdat je leert met andere ogen naar je code te kijken. En elke vaardigheid die je opdoet zorgt dat je groeit als ontwikkelaar (en het staat natuurlijk goed op je CV ;). Mocht je vragen hebben of interessante problemen tegenkomen: laat het me weten. Ik hoor graag van je. Veel succes!

Romke van der Meulen Code-goochelaar

“Ik ben developer bij Vevida. Elke dag leer ik nieuwe dingen over het ontwikkelen van webapps, en ik houd ervan die kennis weer te delen met anderen.”