Akadálymentes gomb

A cikk témái

Egy weboldalon vagy webalkalmazásban elhelyezett gomb nem csak attól lesz gomb, hogy kattintható és vizuálisan úgy néz ki, mint egy gomb. Lényeges, hogy a billentyűzetről is elérhető és aktiválható legyen, illetve a képernyőolvasó is gombnak érzékelje.

Az elfeledett button jelölőelem

HTML-ben általános célú nyomógombot legegyszerűbben a button jelölőelem segítségével hozhatunk létre:

<button type="button">Mutasd</button>

Ez az elem a bevezetőben említett összes akadálymentességi kritériumnak megfelel. Vagyis:

  • a böngészőprogramok gyári stíluslapja alapján is gombnak néz ki
  • egérrel kattintható (érintőképernyőn megtapintható)
  • a tab billentyű segítségével ráállítható a fókusz, majd az enter vagy a szóköz billentyű megnyomásával aktiválható
  • a képernyőolvasó az elemhez érve megérti majd beolvassa, hogy gombhoz érkezett (esetünkben például úgy, hogy Mutasd gomb)

Ha ilyen jó tulajdonságokkal rendelkezik a button jelölőelem, akkor miért tapasztalható mégis az, hogy a fejlesztők többsége nem ezt használja?

Ennek elsősorban az lehet az oka, hogy régebben az űrlapelemeket, és így a button jelölőelemet is, csak nagyon nehezen lehetett CSS segítségével egyedi megjelenésűre formázni. Volt olyan böngészőprogram, ami egyszerűen nem engedte, hogy a gyári vizuális megjelenést felülbíráljuk. Ma már a legelterjedtebb böngészőprogramoknál nincs ilyen kötöttség, vagyis a button elem szabadon formázható. A fejlesztők azonban mégis megmaradtak azoknál a trükkös megoldásoknál, amikor egyéb HTML elemekből (például div, span vagy a elemekből) készítettek kattintható és tetszőleges megjelenésű „álgombokat”. Ezek a megoldások azonban komoly akadálymentességi problémákat okozhatnak. Nézzük, hogy mik ezek, és hogyan lehet őket kivédeni.

Linkből gyártott gomb

Ennél a megoldásnál az a jelölőelemet használják úgy, hogy a link vizuálisan gombnak nézzen ki, és rákattintva a megadott JavaScript kód fusson le.

<a onclick="mutasd()">Mutasd</a>

Ez akadálymentességi szempontból többszörösen rossz. Egyrészt a tab billentyű segítségével nem állítható rá a fókusz, és így az enter billentyű megnyomásával sem aktiválható. Másrészt a képernyőolvasó ezt sima hivatkozásnak (linknek) érzékeli, így például csak annyit olvas be, hogy Hivatkozás Mutasd. Ez félrevezető, hiszen a hivatkozást azért hívjuk hivatkozásnak, mert elnavigál valahová. Ellentétben a gombbal, ami valamilyen akciót végez az adott oldalon. Megjegyzem, létezik olyan képernyőolvasó, amelyik az elemre rákötött kattintási eseménykezelő miatt azt olvassa be, hogy Mutasd kattintható.

Az akadálymentes billentyűzetes kezelés kérdése részben megoldható azzal, ha az a elem kap egy href attribútumot, hiszen ilyenkor a böngészőprogram gyárilag felveszi ezt az elemet is a fókuszálható elemek közé. Bevett szokás, hogy a href attribútumba a kettőskereszt karakter kerül, ami az adott oldalra visszamutató linket reprezentálja.

<a href="#" onclick="mutasd()">Mutasd</a>

Ilyenkor természetesen gondoskodni kell arról is, hogy a JavaScript kód letiltsa a link eredeti funkcióját, azaz ne ugorjon sehová. Ez a preventDefault() vagy a return false segítségével oldható meg.

Ettől persze a képernyőolvasó számára ez még mindig csak egy hivatkozásnak látszik, ami nem visz sehová. Ennek kiküszöbölésére az ARIA szabványt hívhatjuk segítségül. Ha az elem ARIA role attribútumába a button értéket adjuk meg, akkor azt tudatjuk a böngészőprogrammal, és rajta keresztül a képernyőolvasóval is, hogy ez az elem egy gomb szerepét tölti be.

<a href="#" role="button" onclick="mutasd()">Mutasd</a>

A képernyőolvasó ezt már úgy fogja felolvasni, hogy Mutasd gomb.

Némi küzdelem árán tehát elértük azt, amit egyébként a button jelölőelem alapból tud.

Egyéb elemből (például div-ből) gyártott gomb

Ha más jelölőelemből (például div-ből vagy span-ből) készítjük a gombot, akkor még rosszabb helyzetben leszünk, mint a link esetén. Nézzük a legrosszabb helyzetet:

<div onclick="mutasd()">Mutasd</div>

Ez minden akadálymentességi szimptómát produkálni fog, amit az első linkes példánál tapasztaltunk. Sőt, a képernyőolvasó ebben az esetben simán csak annyit fog beolvasni, hogy Mutasd. Ebből egy vak felhasználó nem tudja, hogy ezt az elemet megnyomhatja. Esetünkben talán a gomb szövegének nyelvtani megfogalmazásából kikövetkeztetheti, de erre nem minden esetben számíthatunk. Itt is igaz, hogy némelyik képernyőolvasó az onclick attribútum jelenléte miatt a Mutasd kattintható szöveget olvassa be, ami némi segítséget nyújthat.

Persze itt is használhatjuk az ARIA role attribútumát, annak érdekében, hogy a div a gomb szerepét öltse magára, így a képernyőolvasó Mutasd gomb szöveget olvassa be:

<div role="button" onclick="mutasd()">Mutasd</div>

Viszont a billentyűzetes kezelés problémája itt halmozottan jelentkezni fog. Egyrészt a div elem gyárilag nem kapja meg a fókuszt, vagyis azok a felhasználók, akik csak billentyűzetet képesek használni, a tab billentyűvel nem tudnak ráállni a gombra. Ezt a nagyon komoly akadálymentességi problémát úgy oldhatjuk meg, ha az elemnek tabindex attribútumot állítunk be, mégpedig 0 értékkel. Ez azt eredményezi, hogy a böngésző felveszi ezt az elemet a fókuszálható elemek közé, mégpedig sorrendben úgy, ahogy a HTML kódban (pontosabban a DOM fában) elhelyezkedik.

<div role="button" tabindex="0" onclick="mutasd()">Mutasd</div>

Ezzel azonban csak a probléma egyik részét oldottuk meg. A felhasználó ugyan már ráviheti a fókuszt az elemre, de hiába nyomja meg az enter vagy a szóköz billentyűt, a gombot nem tudja aktiválni. A böngészőprogramok többsége ugyanis egyszerűen nem küld click (kattintási) eseményt, ha az elem fókuszban van és az enter gombot lenyomjuk. Ezt a viselkedést csak a hivatkozásoknál (linkeknél), illetve a valódi HTML gomboknál csinálják, ezért nem merült fel ez a kérdés a linkből gyártott gomb példánknál.

A megoldás az lesz, hogy a keydown (billentyűlenyomás) eseményre is ugyanazt a funkcionalitást (példánkban a mutasd nevű függvényt) kell rákötnünk, mint amit a click-nél rákötöttünk. Ez azonban csak látszólag egyszerű, hiszen figyelnünk kell azt is, hogy melyik billentyűt nyomta le a felhasználó. Ugyanis nekünk, ebben a szituációban csak az enter és a szóköz billentyű lenyomása érdekes, a többi nem. Ha erre nem figyelünk, akkor a felhasználó mondjuk a tab billentyű lenyomásával is aktiválhatná a gombot, amivel egy újabb akadálymentességi problémát okozunk neki, hiszen ő csak a fókuszt akarja továbbléptetni.

A példánkban a HTML kódot úgy alakíthatjuk át, hogy a gombnak adunk egy id attribútumot, és az eseménykezelőt JavaScript-ből kötjük rá a gombra, ami a diszkrét JavaScript elvének is jobban megfelel:

<div role="button" tabindex="0" id="gomb">Mutasd</div>

A DOM szabvány szerinti eseménykezelést használó JavaScript kód valami ilyesmi lehetne:

var gomb = document.getElementById("gomb");

gomb.addEventListener("click", function() {
   mutasd();
},false);

gomb.addEventListener("keydown", function(esemeny) {
   // az enter kódja 13, a szóköz kódja 32
   if ((esemeny.keyCode===13) || (esemeny.keyCode===32)) {
      mutasd();
   }
},false);

Ha jQuery-t használunk, akkor ez:

$("#gomb").bind("click keydown", function(esemeny) {
   // az egér bal gombja 1, az enter kódja 13, a szóköz kódja 32
   if ((esemeny.which===1) || (esemeny.which===13) || (esemeny.keyCode===32)) {
      mutasd();
   }
}

Ez jól tükrözi azt a fontos akadálymentességi irányelvet, hogy ami egérrel működtethető, az billentyűzetről is az legyen.

Összegzés

Ha akadálymentes gombot szeretnénk csinálni, akkor két lehetőség kínálkozik, melyek közül egyértelműen az első a preferált:

  1. Használjuk bátran a button, vagy az input type="button" jelölőelemet, amit azután CSS-ben formázzunk meg úgy, ahogy szeretnénk.
  2. Ha mégis más jelölőelemből készítünk „álgombot”, akkor gondoskodjunk róla, hogy az egérkattintás mellett billentyűzettel is fókuszálható és aktiválható legyen, illetve a képernyőolvasó is felolvassa a szerepét.

Az itt ismertetett elvek egyébként a gombon túl minden egyéb interaktív elem esetén is fontosak. Általános tanács, hogy lehetőleg mindig a rendelkezésre álló natív HTML elemet használjuk az adott célra, és „ne találjuk fel a spanyolviaszt” más elemekből.

Ügyeljünk arra is, hogy a billentyűzetes használat esetén a fókuszjelző mindig látható legyen, hiszen ellenkező esetben a felhasználó nem tudja, hogy melyik gombon tartózkodik éppen. Ezzel a kérdéssel a Miért helytelen egyszerűen lenullázni a CSS outline tulajdonságot? című cikkem foglalkozik részletesen.

Végezetül egy utolsó akadálymentességi szempont, amit szintén érdemes megfontolni. Ha a gomb megnyomása (aktiválása) mindenképpen egy JavaScript kódot futtat le, azaz JavaScript nélkül nem is működőképes, akkor a gomb ne a HTML kódban legyen definiálva, hanem egy JavaScript kód helyezze el a DOM fába. Így ugyanis elkerülhető, hogy azon felhasználóknak, akiknek a JavaScript réteg valamilyen oknál fogva nem elérhető, nem jelenik meg olyan gomb, ami nem csinál semmit.

Demó

A cikkben szereplő gombtípusokat kipróbálhatja a cikkhez készült demó oldalon.