Další ARIA parametry prakticky: aria-describedby, aria-hidden a aria-disabled
Seriál: Praktický vhled do WAI-ARIA – díl 4
aria-describedby
Přístupný popis prvku (delší doplňující informaci, ne krátký název) lze navázat na existující text pomocí aria-describedby, který je součástí WAI-ARIA od verze 1.0, platí i v 1.1–1.3.
Co dělá
Doplňuje k prvku popis odkazem na id jiného prvku (nebo víc prvků). Na rozdíl od aria-labelledby, který dává prvku jméno, aria-describedby dává prvku popis: delší, doplňující text, který čtečka přečte až po jméně a roli:
<button aria-describedby="smazat-popis">Smazat</button>
...
<p id="smazat-popis">Položka se přesune do koše a natrvalo smaže po 30 dnech.</p>
Čtečka ohlásí „Smazat, tlačítko. Položka se přesune do koše a natrvalo smaže po 30 dnech.“
Na co se aplikuje
Lze použít na libovolné roli a libovolném prvku HTML. Na rozdíl od pojmenovacích atributů tu totiž neexistuje seznam rolí, kde by to bylo zakázané. Typicky formulářová pole s nápovědou nebo chybovou hláškou, tlačítka s netriviálním důsledkem akce, prvky s doplňujícím kontextem:
<input type="password" aria-describedby="heslo-pozadavky">
<p id="heslo-pozadavky">Nejméně 8 znaků, jedno číslo a jedno velké písmeno.</p>
Více odkazovaných ID
Hodnota může obsahovat víc id oddělených mezerou. Stejně jako u aria-labelledby se jejich texty spojí v pořadí, v jakém jsou v aria-describedby vypsané:
<input type="text" aria-describedby="format-napoveda datum-chyba">
<p id="format-napoveda">Formát: DD.MM.RRRR</p>
<span id="datum-chyba">Neplatné datum</span>
Omezení
- Odkazovaný prvek nemusí být viditelný — může existovat jen kvůli čtečce, typicky skrytý běžnou „sr-only“ technikou a odkrytý třeba tlačítkem „více informací“.
- Neexistuje-li odkazované
idna stránce,aria-describedbyse prostě neuplatní: žádná chyba, popis se jen nezobrazí. - Není to náhrada za
aria-label/aria-labelledby— popis se čte až po jméně a roli, nikdy místo nich, a prvek bez jména a jen s popisem zůstává nepojmenovaný.
Hodnota a vztah k jiným atributům
Hodnota je seznam jednoho nebo víc id oddělených mezerou, stejný formát jako aria-labelledby, jen s jiným účelem: jméno (aria-labelledby) vs. popis (aria-describedby). Existuje i aria-description pro přímý textový popis bez potřeby odkazovaného prvku, ale s výrazně nižší podporou u čteček než aria-describedby.
Proč to takhle je
- Popis se čte samostatně až po jméně a roli prvku. Proto
aria-describedbynenahrazuje pojmenování, jen ho doplňuje. - Odkazovaný prvek se použije, i když je sám označený
aria-hidden="true". Výpočet přístupného popisu totiž tento atribut na cílovém prvku ignoruje. Naopakhiddennebodisplay:noneprvek z DOMu skutečně odstraní a odkaz na něj se neuplatní. - Kombinace víc
idumožňuje poskládat popis z kousků textu, které jsou jinak v DOM samostatné (typicky nápověda + chybová hláška vedle sebe).
Příklad správného použití
<label for="email">E-mail</label>
<input type="email" id="email" aria-describedby="email-napoveda">
<p id="email-napoveda">Použijeme ho jen pro odpověď na váš dotaz.</p>
Čtečka ohlásí „E-mail, textové pole, Použijeme ho jen pro odpověď na váš dotaz.“ Popis existuje jako normální viditelný text vedle pole. aria-describedby ho jen navíc naváže na konkrétní pole, aby ho čtečka přečetla spolu s ním.
aria-hidden
Prvek zůstává vidět, ale zmizí z toho, co čtečka vůbec „vidí“. Přesně to dělá aria-hidden, který je součástí WAI-ARIA od verze 1.0, platí i v 1.1–1.3.
Co dělá
Odstraní prvek a všechny jeho potomky ze stromu přístupnosti. Čtečka o něm pak neví, i když je na stránce normálně vidět:
<span aria-hidden="true">...</span>
Ozdobná značka se vizuálně zobrazí, ale čtečka ji přeskočí, jako by tam nebyla.
Na co se aplikuje
Nejčastěji na dekorativní inline SVG ikony vedle textu, který už stejnou informaci nese. <img> má na dekorativnost vlastní mechanismus (alt=""), ale SVG žádný alt nemá, takže se to tam řeší přes aria-hidden. Dál se hodí na zdvojený nebo redundantní text, případně na obsah dočasně nedostupný jen vizuálně:
<button type="button">
<svg aria-hidden="true" focusable="false">...</svg>
Uložit
</button>
Ikona je čistě dekorativní, celou informaci nese viditelný text „Uložit“.
Omezení
- Nikdy se neaplikuje na fokusovatelný prvek ani na jeho rodiče, protože by ho čtečka přeskočila, ale klávesnicí by se na něj pořád dalo dostat (Tab), což je matoucí past: uživatel se dostane na „neviditelný“ prvek, o kterém čtečka mlčí.
- Nepoužívat tam, kde je prvek skrytý už jinak, protože
hidden,display:nonenebovisibility:hiddenprvek ze stromu přístupnosti odstraní samy,aria-hiddennavíc nic neřeší. aria-hidden="false"nepřebije rodiče, takže je-li nadřazený prvekaria-hidden="true", potomek saria-hidden="false"se stejně neodkryje, protože dědičnost jde odshora dolů.
Hodnota a vztah k jiným atributům
Hodnota je true nebo false. Bez tohoto atributu se přítomnost prvku ve stromu přístupnosti řídí jen tím, jestli je vůbec vykreslený. Je tu ale jedna výjimka, protože aria-describedby a aria-labelledby použijí text cílového prvku pro výpočet jména nebo popisu, i když má ten prvek aria-hidden="true" (viz výše). Tenhle atribut totiž zablokuje jen to, aby byl prvek vidět jako samostatná položka stromu přístupnosti, ne jeho použití jako zdroje textu pro jiný prvek.
Proč to takhle je
- Prvky odstraňuje jen z rozhraní pro asistivní technologie, ne vizuálně. Proto se nehodí jako náhrada za skutečné skrytí (
hidden,display:none), jen jako doplněk k redundantnímu nebo dekorativnímu obsahu, který má zůstat vidět. - Fokusovatelný prvek s
aria-hidden="true"je past, protože uživatel čtečky se na něj dostane klávesnicí, ale nic mu o něm neřekne.
Příklad správného použití
<a href="/kosik">
<svg aria-hidden="true" focusable="false">...</svg>
Košík (3 položky)
</a>
Čtečka ohlásí jen „Košík (3 položky), odkaz“. Ikonu díky aria-hidden úplně přeskočí. Text „Košík (3 položky)“ nese celou informaci sám, ikona vedle něj jen opakuje, co je vidět.
aria-disabled
aria-disabled nechává prvek nefunkční, ale pořád dosažitelný a čitelný, na rozdíl od nativního HTML atributu disabled. Je součástí WAI-ARIA od verze 1.0, platí i v 1.1–1.3.
Co dělá
Sdělí čtečce, že prvek je vnímatelný, ale momentálně needitovatelný nebo neovladatelný. Na rozdíl od disabled ho ale nevyřadí z pořadí procházení Tabem a nic sám o sobě nezmění vizuálně ani funkčně:
<div role="button" tabindex="0" aria-disabled="true">Odeslat</div>
Čtečka ohlásí „Odeslat, tlačítko, zakázáno“, ale tlačítko zůstává ve fokusovém pořadí, na rozdíl od <button disabled>, který by z něj úplně zmizel.
Na co se aplikuje
Kdekoliv, kde má needitovatelný nebo neovladatelný prvek zůstat dosažitelný a čitelný, ne úplně zmizet z pořadí procházení pomocí klávesnice: typicky vlastní ovládací prvky postavené na <div>/<span> s role, nebo tlačítka, u kterých má uživatel pořád vidět, že existují, a proč jsou momentálně nedostupná, ne jen že chybí:
<button type="button" aria-disabled="true">Odeslat (vyplňte formulář)</button>
Omezení
- Sám o sobě nic nevypíná — na rozdíl od
disabledmusí kliknutí nebo aktivaci zablokovat vlastní kód,aria-disabledjen informuje čtečku. - Sám o sobě nic nemění vizuálně — potřebuje vlastní CSS (
[aria-disabled="true"] { opacity: .5; }apod.), jinak vypadá stejně jako funkční prvek. - Na kontejneru zakáže i potomky, takže
aria-disabled="true"se na obalujícím prvku dědí na všechny fokusovatelné potomky, i ty, co zakázat nechtěl. pointer-events: nonenestačí — zablokuje myš, ne klávesnici. Funkčnost musí zablokovat kód, ne jen CSS.
Hodnota a vztah k jiným atributům
Hodnota je true nebo false. U nativních formulářových prvků existuje i HTML atribut disabled, ten prvek navíc vyřadí z fokusu, ze sekvence odeslání formuláře a automaticky mu dá výchozí vzhled (:disabled v CSS). aria-disabled nic z toho samo nedělá, jen sdělí stav. Zbytek je na autorovi.
Proč to takhle je
- Zůstat fokusovatelný a čitelný má smysl tam, kde uživatel potřebuje vědět, že prvek existuje, a proč je nedostupný. Nejde o to ho úplně ztratit z procházení klávesnicí, jako by tam nikdy nebyl.
- Typický případ: tlačítko „Odeslat“ dostupné, jen dokud formulář není validní.
disabledby ho úplně schovalo z pořadí Tabu,aria-disabledho ale nechá na místě a čtečka pak může ohlásit i důvod, je-li napsaný (např. přesaria-describedby).
Příklad správného použití
<button type="button" aria-disabled="true" aria-describedby="odeslat-duvod">Odeslat</button>
<p id="odeslat-duvod">Formulář obsahuje chyby, opravte je před odesláním.</p>
Čtečka ohlásí „Odeslat, tlačítko, zakázáno, Formulář obsahuje chyby, opravte je před odesláním.“ Tlačítko zůstává dosažitelné klávesnicí, popis přes aria-describedby z první části tohoto dílu ohlásí i důvod, a samotné zablokování kliknutí nebo aktivace zajistí kód (zde kvůli přehlednosti vynechaný).