Hogyan adjunk akadálymentes nevet?

A cikk témái

A weboldal számos elemének – különösképpen az interaktív
komponenseknek – nevet kell adnunk. A név alapvetően arra szolgál,
hogy egy rövid és érthető információt nyújtson az adott
komponens céljáról
, valamint egyértelműen beazonosíthatóvá tegye azt.

E két tényező elsősorban azon felhasználóinknak fontos,
akik valamilyen speciális kisegítő eszközzel (például
képernyőolvasó programmal vagy hangvezérléssel) böngészik az
oldalunkat
.

Ha például egy vak felhasználó ránavigál
egy komponensre, akkor a képernyőolvasó program a komponens típusa
(szerepe) mellett a komponens nevét is beolvassa. Vagy ha egy
mozgássérült felhasználó a beszédfelismerő eszközének kimondja a
komponens nevét, akkor az eszköz a név alapján már képes
beazonosítani, és kérésre akár aktiválni is a kiválasztott
komponenst.

A név definiálása nem teljesen triviális. Legalábbis abban az
értelemben nem, hogy a HTML-ben nincs csak egy,
kifejezetten erre a célra dedikált attribútum
. Ugyan
létezik a name attribútum, de ez abszolút más
célokat szolgál.

Alapszabályként lefektethetjük, hogy a legegyszerűbb
esetekben a komponens neve elvileg ugyanaz lesz, mint a
komponens vizuálisan is látható címkéje (szövege)
.
Például egy szöveges gombnál a gomb felirata (mondjuk a
„Kiszámolom” szöveg) egyben a gomb neve is lehet. Vagy egy
űrlapmezőnél a logikailag hozzákapcsolt <label>
címke szövege biztosíthatja a nevet.

Ugyanakkor a név sok esetben a komponens egy láthatatlan
tulajdonságából is származhat
. Gondoljuk például egy
olyan gombra, amin csak egy ikon látszik. Ilyenkor a fejlesztő
döntésétől függ, hogy az ikon szöveges alternatívájával, a gomb vizuálisan rejtett, de képernyőolvasóval elérhető szövegével, vagy
esetleg a gomb <button> jelölőelemének
valamelyik attribútumával szeretné definiálni a gomb nevét.

Az mindig a komponens pontos típusától függ, hogy mely
HTML attribútumok definiálhatják a nevét
. Így például a
title, a value, vagy az alt
attribútumok is szóba jöhetnek, amennyiben a HTML szabvány
megengedi ezen attribútumok használatát az adott jelölőelemnél. De
az WAI-ARIA szabványban
definiált aria-label, illetve aria-labelledby
tulajdonságokkal (attribútumokkal) is operálhatunk. Ráadásul
ezeket kötöttség nélkül, bármely HTML jelölőelemnél használhatjuk.

A névkalkulációs algoritmus

Fontos azonban tudni, hogy az említett
lehetőségekkel csak potenciális „névjelölteket” definiálunk
.

A komponens tényleges nevét ugyanis a böngészőprogram egy
vagy több ilyen potenciális névjelöltből kalkulálja ki
,
majd a kikalkulált nevet eltárolja az úgynevezett
akadálymentességi fában
(angolul accessibility tree). Az akadálymentességi fára ebben a cikkemben nem
szeretnék részletesen kitérni. Most csak annyit jegyeznék meg
róla, hogy ez az az objektumstruktúra, amit a
böngészőprogramok a különböző kisegítő eszközök kiszolgálására
állítanak össze
. Ezek az eszközök ugyanis elsődlegesen
nem a HTML kódból vagy a DOM fából, hanem a böngészőprogram által
legenerált akadálymentességi fából olvassák ki a weboldal
objektumaira vonatkozó információkat. Például ebből szerzik meg a
képernyőolvasó programok is a weboldal komponenseinek nevét.

Szerencsére a böngészőprogramok által alkalmazott névkalkulációs algoritmus ma már jól specifikált. Az Accessible Name and
Description Computation
, illetve a HTML Accessibility API Mappings című W3C specifikációk
részletesen leírják az algoritmus lépéseit, így egyre kisebb lesz
az esélye annak, hogy az egyes böngészőprogramok különböző nevet
kalkulálnának az adott komponenshez.

Ugyan az említett specifikációk alapvetően a böngészőgyártók
számára készültek, de nekünk is érdemes tisztában lennünk
a névkalkulációs algoritmus alapjaival
. Főleg azért,
mert ha a fejlesztés során – szándékosan vagy véletlenül – több
névjelöltet is definiálunk ugyanahhoz a komponenshez, akkor nem
árt tudni, hogy ezekből melyik kerül ki majd győztesen, azaz
melyik lesz a komponens tényleges neve.

A névkalkuláció algoritmusa egy szigorú sorrendiségen
alapszik.
A böngészőprogram egy előre meghatározott
sorrendben megnézi, hogy a potenciális névjelöltek közül melyik
definiált és érvényes. Az első megfelelő jelölt lesz a
tényleges név
, a többi nem játszik. Ha a
böngészőprogram nem talál használható névjelöltet, akkor a
komponensnek nem lesz neve.

A névjelöltek erősorrendje nagyon vázlatosan így néz ki:

  1. aria-labelledby attribútum
  2. aria-label attribútum
  3. az adott komponens jelölőeleméhez engedélyezett speciális
    attribútum (pl. alt, value), vagy a
    logikailag hozzákapcsolt címke (pl. <label>,
    <caption>, stb.)
  4. az adott komponens szöveges tartalma (ha a komponensnek lehet
    ilyenje)
  5. title attribútum

Vegyünk egy eléggé életszerűtlen, de annál szemléletesebb példát.
Legyen a komponensünk egy gomb, amit az alábbi kóddal definiálunk:

<button aria-label="Az aria-label nyert" title="A title nyert">A szöveges tartalom nyert</button>

Természetesen vizuálisan egy olyan gomb fog megjelenni,
aminek felirata
A szöveges tartalom nyert
szöveg
lesz. Elvileg ez a szöveges tartalom is egy
lehetséges névjelölt. De mivel a gomb aria-label és
title attribútuma is definiálva van, és mindkettő a
specifikációnak megfelelően érvényes, ezért a fenti
erősorrendből adódóan az
aria-label
fog nyerni
, vagyis ez adja a nevet. Ezért például a
képernyőolvasó program is így fogja felolvasni a komponenst:

Gomb, Az aria-label nyert

Megjegyzés: nagyon fontos, hogy a
komponens nevébe soha nem kell beleírni, hogy az milyen elem

(például egy gomb). Ez az információ ugyanis a komponenst
definiáló HTML jelölőelem szemantikájából, vagy ennek hiányában a
role attribútumának értékéből jön. Példánkban a <button>
jelölőelem miatt olvassa fel a képernyőolvasó, hogy Gomb.

A névkalkuláció monitorozása

A Chrome böngésző fejlesztői eszköztárában van egy
nagyon jó névkalkulációs monitorozóeszköz
, ami az Accessibility fül Computed
Properties
lenyílójában található.

Képernyőfotó egy kinyitott fejlesztői eszköztárral rendelkező Chrome
böngészőablakról, amiben a példánk HTML kódja, a névkalkulációs
monitorozóeszköz, és legenerált weboldal látszik.
A Chrome fejlesztői eszköztárának névkalkulációs monitora

Ahogyan a fenti képernyőképen is látszik, a Name
tulajdonság mindig megmutatja a kijelölt komponens
kikalkulált nevét
(példánknál Az aria-label nyert
szöveget), és a kalkulációhoz felhasznált összes
névjelöltet
. Utóbbiaknál azt is megmutatja, hogy melyek nem voltak megadva (Not specified), és
áthúzással jelöli azokat, amelyek kiestek a kalkulációból.
Esetünkben Not specified értékű az aria-labelledby
és a From label (vagyis a logikailag
hozzákapcsolt <label> elemből származó)
névjelölt. Míg A szöveges tartalom nyert szövegű Contents (vagyis a szöveges tartalom) és A
title nyert
értékű title attribútum át van
húzva.

A képen az is jól látszik, hogy a weboldalon A szöveges tartalom nyert feliratú gomb jelenik meg. Tehát a gomb felirata és a neve teljesen eltér egymástól, ami nem helyes. De erről majd később.

Adjunk értelmes nevet a Tovább… linkeknek

Nézzünk most egy olyan példát, ami életszerűbben mutatja a
névkalkuláció előnyeit. Tételezzük fel egy olyan kódrészletet,
amiben egy hír címe, bevezetője, és a hírre mutató Tovább
olvasom
szövegű link található.

<h2>Átadásra került Budapest 15. mentőállomása a Szent Márton Gyermekmentő Szolgálat jóvoltából</h2>
<p>A Szent Márton Gyermekmentő Szolgálat még többet szeretne tenni a hazai sürgősségi gyermekmentés ügyéért, ezért vásárolt és felújított egy ingatlant, amely a Gyermekrohamkocsinak új „otthont” ad, a gyermekmentésnek egy oktatási központot biztosít, továbbá bővíti az Országos Mentőszolgálat budapesti mentőállomásainak hálózatát.</p>
<p><a href="mentoallomas.html">Tovább olvasom</a></p>

A kódban található három elem közül most koncentráljunk a linkre,
vagyis az <a> elemre.

Mivel ennek a linknek most csak egy névjelöltje van
(maga a link szövege), így a kikalkulált neve is a Tovább
olvasom
lesz. Ez annyiból nem szerencsés, hogy önmagából ebből a névből nem derül ki, hogy pontosan melyik hírt
tudja majd elolvasni a képernyőolvasós felhasználó, ha aktiválja a
linket. A WCAG
akadálymentességi szabvány 2.4.4-es alapkövetelménye
is
előírja, hogy a link szövege lehetőleg önmagában is
ismertesse a link célját
. A képernyőolvasó program
ugyanis most valami ilyesmit fog neki felolvasni, ha rálép a
linkre:

Link, Tovább olvasom

A problémát több módon is orvosolhatjuk.

Az egyik lehetőség, hogy egy vizuálisan rejtett, de képernyőolvasóval elérhető szövegrészletet
illesztünk a link végére, így a link képernyőolvasós neve a Tovább olvasom szöveg mellett (után) tartalmazni fogja a hír címét
is:

<a href="mentoallomas.html">Tovább olvasom <span class="vizualisrejtes">Átadásra került Budapest 15. mentőállomása a Szent Márton Gyermekmentő Szolgálat jóvoltából</span></a>

Így a képernyőolvasó program ezt fogja felolvasni, ha a
felhasználó rálép a linkre:

Link, Tovább olvasom Átadásra került Budapest 15. mentőállomása
a Szent Márton Gyermekmentő Szolgálat jóvoltából

Az aria-label alkalmazása

Egy másik megoldás lehet az, ha a linknek a szöveges tartalmánál
erősebb névjelöltet definiálunk, mondjuk az aria-label
attribútumon keresztül. Ilyenkor akár még egy szebb, kerekebb
nevet is megfogalmazhatunk:

<a href="mentoallomas.html" aria-label="Tovább olvasom az Átadásra került Budapest 15. mentőállomása a Szent Márton Gyermekmentő Szolgálat jóvoltából című hírt">Tovább olvasom</a>

Fontos, hogy változatlanul Tovább
olvasom
lesz a link látható szövege, csak
a neve lesz bővebb szövegű
. Egy képernyőolvasó
jellemzően így fogja felolvasni:

Link, Tovább olvasom az Átadásra került Budapest 15.
mentőállomása a Szent Márton Gyermekmentő Szolgálat jóvoltából
című hírt

További megoldás lehet, ha a legerősebb névjelöltet, vagyis az aria-labelledby
attribútumot vetjük be.

Az aria-labelledby alkalmazása

Az aria-labelledby
attribútum lényege, hogy a komponens nevét id
értékkel azonosított komponens (vagy komponensek) kikalkulált
nevéből „szedjük össze”.

Ha csak egy id értéket
adunk meg, akkor a komponens neve az adott id
értékkel azonosított komponens kikalkulált neve lesz.

Ha szóközökkel elválasztva több id értéket sorolunk
fel, akkor a komponens neve a felsorolt id
értékekkel azonosított komponensek kikalkulált neve lesz, mégpedig
a felsorolás sorrendjében.

Érdekesség, hogy egy komponens
visszahivatkozhat a saját id értékére is, de a
névkalkulációs algoritmus specifikációja alapján ez nem
fog végtelen rekurziót eredményezni
.

Tegyünk néhány id attribútumot a példakódunkba,
hogy az aria-labelledby bevethető legyen. Adjunk egy
id attribútumot a <h2> címsornak,
és egyet a linknek is:

<h2 id="hir-1-cim">Átadásra került Budapest 15. mentőállomása a Szent Márton Gyermekmentő Szolgálat jóvoltából</h2>
<p>A Szent Márton Gyermekmentő Szolgálat még többet szeretne tenni a hazai sürgősségi gyermekmentés ügyéért, ezért vásárolt és felújított egy ingatlant, amely a Gyermekrohamkocsinak új „otthont” ad, a gyermekmentésnek egy oktatási központot biztosít, továbbá bővíti az Országos Mentőszolgálat budapesti mentőállomásainak hálózatát.</p>
<p><a href="mentoallomas.html" id="hir-1-link">Tovább olvasom</a></p>

Megjegyzés: Azért használok számozást az id
értékekben, mert feltételezhetően több hír is lesz az oldalon, és
az id
értékeknek muszáj teljesen egyedieknek lenniük
. Sajnos
az akadálymentességi auditok során sok olyan weboldallal találkoztam, ahol az id
értékek nem volt egyediek, így bizonyos komponensek teljesen rossz
nevet kaptak.

Most már definiálhatunk egy aria-labelledby
attribútumot a linknek, amiben először a link saját id
értékét, majd a hírcím id értékét soroljuk fel:

<a href="mentoallomas.html" id="hir-1-link" aria-labelledby="hir-1-link hir-1-cim">Tovább olvasom</a>

Így a link kikalkulált neve az lesz, hogy Tovább olvasom
Átadásra került Budapest 15. mentőállomása a Szent Márton
Gyermekmentő Szolgálat jóvoltából
. Természetesen a vizuális
linkszöveg változatlanul csak annyi, hogy Tovább olvasom.

Tipikus hiba, ha nem figyelünk a névkalkulációra

A következő példa egy olyan akadálymentességi hibát mutat be,
amivel sajnos sok weboldalon találkozom, és ebben is a
névkalkuláció játssza a főszerepet.

Vegyünk egy olyan linket, amibe egy ikon fonttal megvalósított
ikont teszünk:

<a href="reszletek.html" title="Részletek"><span class="ikon"></span></a>

Egy korábbi cikkemben már írtam az ikon fontok használatának akadálymentességi anomáliáiról,
amiben érintettem a névadás problémáját is.

A fenti kódnál is az a kérdés, hogy vajon mi lesz a link neve.

Sokan talán azt tippelik, hogy mivel a linkünknek nincsen
szöveges tartalma, de van title attribútuma, ezért a
névkalkulációs algoritmus alapján az ebben definiált Részletek
szöveg lesz a kikalkulált név. Ez azonban rossz tipp, mert ez a
link csak látszólag üres
. És ebből adódik az akadálymentességi
hiba is.

Az ikon font technikára jellemző, hogy az ikont CSS-ből, a content
tulajdonság segítségével illesztjük be egy HTML jelölőelem elé
vagy mögé. Anno arról is írtam már egy cikket, hogy vajon valódi tartalomnak tekinthető-e a CSS-ből beillesztett content.
Az biztos, hogy a névkalkulációs algoritmus alapján a ::before és az ::after pszeudoelemek beillesztett tartalma is része lesz az adott komponens szöveges tartalmának.

Példánkban tehát a link szöveges tartalma az az egy darab Unicode
karakter lesz, ami az ikon fontot reprezentálja. Vagyis a
link kikalkulált neve is ez az egy darab Unicode karakter lesz
!
Ne feledjük, hogy a szöveges tartalom erősebb névjelölt, mint a title,
tehát a névkalkulációnál a title kiesik.

Már csak az a kérdés, hogy az ikont reprezentáló Unicode karakter
vajon értelmes (tehát képernyőolvasóval is felolvasható), vagy
sem. Ha felolvashatatlan a Unicode karakter, akkor a link
neve is felolvashatatlan (értelmetlen) lesz.
A
példánkban szereplő linket mondjuk a VoiceOver képernyőolvasó
program csak így fogja felolvasni:

Link,

Vagyis tényleg úgy hallatszik, mintha üres lenne, ami
egyértelműen akadálymentességi hiba.

Persze abból is galiba lehet, ha esetleg olyan Unicode karakter
reprezentálja az ikont, ami felolvasható, hiszen ilyenkor
elképzelhető, hogy az ikon vizuális megjelenése, és a felolvasott
név köszönőviszonyban sincs.

Megtévesztő lehet, ha valaki mondjuk az NVDA képernyőolvasóval
teszteli le a példában szereplő megoldást. Gyári alapbeállítások
mellett az NVDA képernyőolvasó ugyanis így fogja felolvasni a
linket:

Hivatkozás, Részletek

Most akkor mégis jó a példánk? Hirtelen hogyan lett Részletek
a link neve?

Elárulom, a link neve továbbra is hibás, vagyis üres
(értelmetlen). Az elhangzó Részletek szöveg ugyanis nem a
link neve, hanem a link kiegészítő leírása (bővebb magyarázata)
,
ami történetesen a title attribútumból jön.

Eddig még nem említettem, de a leírás meghatározására is
létezik egy kalkulációs algoritmus
, amit szintén a
hivatkozott W3C specifikációk írnak le. Ugyanúgy beszélhetünk
„leírásjelöltekről”, ezek erősorrendjéről, és a győztes (azaz a
kikalkulált) leírásról. De a leíráskalkulációra most nem térnék ki
részletesen.

A kiegészítő leírást egyébként a VoiceOver képernyőolvasó is
felolvassa, de a gyári alapbeállítások mellett csak a név
elhangzása után néhány másodperccel. Vagyis közel sem biztos, hogy
a képernyőolvasós felhasználóhoz eljut ez az információ. Amúgy a
képernyőolvasó programok többségénél saját maga tudja beállítani a
felhasználó, hogy a kiegészítő leírás elhangozzon-e vagy sem, és
ha igen, akkor hogyan.

A példánk tehát jól mutatja, hogy nem szabad túlmisztifikálni a title
attribútum akadálymentességi szerepét. A title az
egyik leggyengébb, és „legingoványosabb” attribútum, amire
akadálymentességi szempontból nem nagyon szabad építeni
.
Valószínűleg a példakódnál is csak azért használták a fejlesztők,
hogy tooltip-ként megjelenhessen, de ezzel kapcsolatban is bőven
akadnak anomáliák.

Példa korrekciójára több megoldás is létezik. Felmerülhet, hogy a
title helyett az aria-label
attribútumot használjuk, ami biztosan nevet fog adni a linknek:

<a href="reszletek.html" aria-label="Részletek"><span class="ikon"></span></a>

A képernyőolvasó szempontjából ez már akadálymentesebb megoldás,
de egyéb szempontok alapján nem igazán. Az ikon fontokról szóló cikkemben is kitérek arra az alapelvre, hogy a CSS-nek nem szabad érdemi információkat közvetítenie. Ha
ugyanis a CSS formázás bármilyen ok miatt nem úgy jelenik meg,
ahogy tervezzük, akkor információvesztés állhat fenn. Márpedig az
ikon fontok ebből a szempontból nagyon sérülékenyek, és ekkor – aria-label
ide vagy oda – a látó felhasználók csak egy üres linket kapnak. Az
említett cikkemben ezt is tovább boncolgatom, és alternatív
megoldásokat is felvázolok.

Zárszó

Végezetül két fontos dolgot emelnék még ki a névkalkuláció kapcsán.

Adhat-e nevet a placeholder?

A névkalkulációs algoritmusban, és így a névjelöltek között sem
szerepel az űrlapmezőknél használható placeholder
attribútum, ugyanis a placeholder nem definiálja az űrlapmező nevét
(címkéjét)
.

Mégis sokan ilyen megfontolásból használják a
helykitöltőt, ami egyértelmű hiba. Erről bővebben a Használható-e a HTML5 placeholder attribútuma űrlapcímkeként?
című cikkemben írok.

Például az alábbi űrlapmezőnek sincsen neve:

<input type="text" placeholder="Vezetéknév">

Ugyanakkor megjegyezném, hogy sajnos a névkalkulációs
specifikációktól eltérően
mégis sok böngészőprogram beleveszi a
névkalkulációba a placeholder értékét is, ami bugnak
tekinthető
. Semmiképpen ne építsünk erre a viselkedésre.

Címke a névben

A 2018 júniusában megjelent új WCAG 2.1
akadálymentességi szabvány 2.5.3 alapkövetelménye
azt írja
elő, hogy a komponens nevében mindenképpen szerepeljen a komponens
vizuálisan is látható címkéje
. Mégpedig lehetőleg a név legelején.

Ez a követelmény azon látó felhasználók érdekében született, akik
hangvezérléssel böngésznek
.

A cikk elején említettem, hogy nekik
egy interaktív komponenst a nevével kell megszólítaniuk, de ezt a
nevet elvileg nem tudják (látják), hiszen a kikalkulált név csak
az akadálymentességi fában van letárolva. Értelemszerűen csak a
komponens vizuálisan is látható címkéjét tudják bemondani
az
azonosításhoz. Ezért fontos, hogy a vizuálisan látható címke
szövege pontosan ugyanolyan alakban (toldalékokkal) legyen benne a
kikalkulált név elején.

Persze ettől a kikalkulált név „hátrafele”
még nyugodtan lehet bővebb szövegű
, ahogyan a Tovább olvasom
példánknál is belefűztük a hír címét. Ezt a szituációt már elvileg
le tudják kezelni a hangvezérlő szoftverek, mint ahogyan azt is,
ha több ugyanolyan címkéjű komponensből kell választania a
felhasználónak.