Dialoogvensters

Gijs Veyfeyken op 27/05/2015 - reageer als eerste

Cet article en français: Fenêtres de dialogue modales

Geen tijd om te lezen? Implementeer deze jQuery Simple and Accessible Modal Window by Nicolas Hoffmann (Github).

Er zijn twee soorten dialoogvenster. Modal dialogs en non modal dialogs. Een modal dialog onderbreekt de gebruiker en vraagt om een antwoord. Je kan niet verder werken tot je het venster sluit. We kennen dit soort vensters van het besturingssysteem dat ons waarschuwt en een bevestiging voor een bepaalde actie vraagt. Bijvoorbeeld als ik een e-mailbericht sluit dat nog niet verzonden is.

dialoogvenster mail app save message as draft

Non modal dialogs zijn gelijkaardig maar onderbreken de applicatie niet. Je kan verder werken terwijl het venster open staat. Denk bijvoorbeeld aan het zoekvenster van Microsoft Word.

dialoogvenster zoekfunctie Word

Beide soorten dialoogvensters zien we ook op het web. Om in te loggen op een dienst, in te schrijven op een nieuwsbrief of om iets te tonen. Bijvoorbeeld de vergrote weergave van een foto. Zelfs video wordt embed in dialoogvensters. Synoniemen op het web zijn lightbox of overlay. Daar schreven we eerder over in de blogpost Lightbox: veel gebruikt, zelden voor iedereen bruikbaar.

In een applicatie kan een non modal dialog nuttig zijn. In een webomgeving is er geen nood aan. De enige uitzondering die we kennen is een cookiemelding. Daarom richten we ons op het gedrag en de vereisten voor een toegankelijke "modal" dialog.

focus management

  1. button opent dialog
  2. focus springt naar parent div of eerste formulierelement
  3. focus springt terug naar button bij het sluiten

Het openen van een dialoogvenster is een actie. Daarom gebruik je best een <button> om het te openen. Liever geen link <a href="">, want je navigeert niet naar een andere pagina.

Bij het openen springt de focus voor toetsenbord - en screenreadergebruikers naar de dialog. Zonder die sprong weet een screenreadergebruiker niet dat er iets is gebeurd. Het lijkt alsof de knop niet werkt. Een toetsenbordgebruiker zal doorheen alle elementen moeten tabben vooraleer hij aan de dialog komt omdat die meestal onderaan in de broncode staat.

Laat de focus daarom naar de parent <div> van de dialog springen. Een alternatief is het eerste formulierelement binnen de dialog. De eerste optie heeft de voorkeur voor blinden. Dan slaat men geen informatie over. De tweede optie is handiger voor toetsenbordgebruikers. De focus zit meteen op het eerste element dat om een actie vraagt (invoerveld of knop).

De focus verplaatsen gebeurt via een .focus() JavaScript event. De <div> van de dialog waar de focus heen moet, kan normaal geen focus krijgen. Een <div> komt niet voor in de tabvolgorde. Dat los je op door het attribuut tabindex="-1" toe te voegen. Tabindex -1 zet het element niet in de tabvolgorde maar zorgt ervoor dat je er met Javascript naartoe kunt springen en focus geven.

Bij het sluiten van de dialog springt de focus terug naar het element (button) dat de dialog opende. Als dit niet gebeurt, is een screenreadergebruiker gedisorriënteerd.

Opgelet, de Supernova screenreader van Dolphin ondersteunt helaas geen focus management en is een populaire screenreader onder blinden en slechtzienden in België. We hebben de ontwikkelaars ingelicht maar ze zien dit tot onze verbazing niet als een probleem. Meer hierover in de blogpost over Supernova en focus management.

Keyboard trap

Het is niet alleen belangrijk dat de focus naar de dialog springt. De focus mag er ook niet buiten gaan. Een modal dialog vraagt een actie van de gebruiker vooraleer die verder kan. In de meeste implementaties kan je met de tabtoets of met een screenreader buiten de dialog gaan. Hoe voorkom je dat?

Plaats een aria-hidden attribuut in alle paginablokken (header, main, footer) die op hetzelfde niveau staan als de dialog. Plaats het niet op een parent element, bijvoorbeeld de body. Toggle dat attribuut via JavaScript van aria-hidden="false" naar aria-hidden="true" wanneer de dialog opent. Voor de <div> van de dialog zelf doe je het omgekeerde. Screenreaders negeren elementen met aria-hidden="true". Door alles behalve de dialog te verbergen, creëer je een toetsenbordval voor screenreaders.

ARIA heeft geen invloed op een normale toetsenbordgebruiker. De keyboard trap voor de tabtoets creër je via JavaScript. Voorbeeld keep focus Github.

Zorg er daarnaast liefst ook voor dat de gebruiker de dialog kan sluiten door op de escape-toets te drukken.

Visuele focus indicator

Je verplaatst de focus en houdt die binnen de dialog voor toetsenbordgebruikers. Vergeet geen visuele focus stijl via CSS toe te voegen. Anders is het voorgaande zinloos. Iemand die door de pagina tabt moet kunnen zien waar de focus is. Browsers geven alle elementen die de focus krijgen, een default outline. Een dotted border in Firefox (Gecko) en Internet Explorer (Trident), een solid border in Chrome en Safari (Webkit). Overschrijf die stijl liever met een duidelijkere outline. Wis ze zeker niet. Let op met reset stylesheets.

Betekenisvolle knoppen

Dialogs hebben vaak een (extra) sluitknop in de vorm van een "x" zoals de sluitknop in vensters van het besturingssysteem. Let erop dat die in de tabvolgorde zit en begrijpelijk is voor een screenreadergebruiker. "x" is niet betekenisvol. Geef de button "sluiten" als opschrift en gebruik een CSS background-image van een "x". Of kies voor een font icon met verborgen tekst.

ARIA

Nog nooit van ARIA gehoord? Lees dan eerst even deze samenvatting.

HTML5 heeft het <dialog> element geïntroduceerd. Er is nog geen ondersteuning door browsers en screenreaders. Met ARIA geven we informatie aan screenreaders waar HTML te kort schiet. In dit geval <div role="dialog"> zodat het wordt aangekondigd als een dialoogvenster.

De dialog wordt nu correct aangekondigd maar heeft nog geen naam. Met het aria-labelledby attribuut koppel je de kop <h1> van je dialog aan de parent <div>.

Sommige screenreaders lezen enkel formulierelementen voor binnen een dialog. Theoretisch is dat correct omdat een modal dialog eigenlijk niet dient om uitgebreide informatie in te steken. Je lost dit op door een child <div role="document"> toe te voegen. Role document zorgt ervoor dat een screenreader in "browse mode" gaat in plaats van "forms mode". Zo wordt alles toch mooi voorgelezen.

Samenvatting

  • Focus verspringt naar modal dialog (omsluitende div) als die opent
  • Focus is visueel duidelijk
  • Focus kan het dialoogvenster niet verlaten
  • Focus gaat terug naar button als dialog sluit
  • Knoppen zijn goed benoemd
  • Laat de dialog ook sluiten met de escape-toets
  • Gebruik role="dialog" voor omsluitende div
  • Gebruik role="document" voor inhoud
  • Gebruik aria-hidden="true" om de rest van de pagina te verbergen voor screenreaders

Voorbeeld

Nicoals Hoffmann heeft een jQuery plugin geschreven die aan alle bovenstaande zaken voldoet.

jQuery Simple and Accessible Modal Window by Nicolas Hoffmann (Github)

modal dialog

Reageer

De volgende HTML tags zijn toegestaan: <a> <b> <ul> <li>