ARIA atributy

Co je WAI-ARIA a proč patří mezi základy moderního webu

WAI-ARIA (Accessible Rich Internet Applications) je soubor atributů HTML definovaný konzorciem W3C, který doplňuje sémantiku a interakce webových komponentů tak, aby byly přístupné uživatelům asistenčních technologií (čtečky obrazovky, alternativní vstupy). ARIA nevytváří vizuální prvky, ale „říká“ strojům, co prvky jsou a co právě dělají. V době aplikací SPA, vlastních komponent a AI/LLM indexace je ARIA klíčová pro přístupnost (a11y), SEO i AIO/AEO – pomáhá vyhledávačům a modelům pochopit strukturu a stavy uživatelského rozhraní.

Zásady: kdy ARIA používat a kdy ne

  • Přednost má nativní HTML. Pokud existuje sémantický prvek (button, nav, header, ul/li, table, form), použijte ho. ARIA je doplněk, ne náhrada.
  • ARIA by neměla měnit vizuální chování. Ovládání klávesnicí a fokus řešte v JS/CSS, ARIA pouze popisuje roli a stav.
  • „Žádná ARIA je lepší než špatná ARIA“. Špatné stavy, špatné reference nebo nesoulad rolí škodí více než žádná ARIA.
  • Konzistence stavu. Atributy jako aria-expanded, aria-selected, aria-checked musí odrážet skutečný stav komponentu.

Stavebnice ARIA: role, vlastnosti, stavy

ARIA se dělí na tři hlavní skupiny:

  • Role (např. role="button", role="dialog", role="navigation") – definují typ widgetu nebo landmarku.
  • Properties (vlastnosti) (např. aria-labelledby, aria-describedby, aria-owns) – stabilní vlastnosti a vztahy.
  • States (stavy) (např. aria-expanded, aria-checked, aria-busy) – proměnné stavy během interakcí.

Landmark role: kostra stránky pro rychlou navigaci

Landmarky umožňují skokovou navigaci čtečkami obrazovky a zároveň pomáhají vyhledávačům a LLM pochopit rozvržení stránky:

  • role="banner" – hlavička webu (obvykle na <header>).
  • role="navigation" – hlavní navigace (často <nav>).
  • role="main" – hlavní obsah (obvykle <main>).
  • role="complementary" – doplňkové panely (sidebar).
  • role="contentinfo" – zápatí (na <footer>).
  • role="search" – vyhledávací formulář.

Používejte nativní prvky (header, nav, main, aside, footer), které implicitně nesou landmark roli. ARIA roli přidávejte pouze tehdy, když nepoužíváte nativní element nebo potřebujete upřesnit význam.

Názvy a popisy: aria-label, aria-labelledby, aria-describedby

  • Viditelný název > aria-label. Pokud prvek již má viditelný text (např. obsah tlačítka), ten je jeho přístupové jméno. aria-label používejte u ikon bez textu.
  • aria-labelledby váže název na jiný element podle id a má vyšší prioritu než aria-label.
  • aria-describedby poskytuje doplňkový popis (tooltip, nápověda), který se čte po názvu.

Příklad ikonického tlačítka bez textu:

<button aria-label="Otevřít menu"></button>

Interaktivní widgety: chování, stavy a klávesnice

U vlastních komponent je nutné sladit roli, stav i ovladatelnost klávesnicí:

  • Tlačítko (button): role="button", aktivace klávesami Enter i Space, fokus přes tabindex="0" (pokud nejde o nativní <button>).
  • Disclosure/Accordion: ovládací prvek s aria-expanded="true|false" a cílový element s aria-hidden nebo řízeným zobrazením; propojení přes aria-controls.
  • Záložky (Tabs): role="tablist" obsahuje role="tab" s aria-selected, panely mají role="tabpanel" a jsou navázány přes aria-controls/aria-labelledby. Šipky mění fokus mezi záložkami.
  • Menu/menubar a listbox: respektujte definované klávesové vzory (šipky, Home/End, Enter/Escape).

Živé oblasti a dynamický obsah: aria-live, aria-busy

Při asynchronních akcích oznamujte změny:

  • aria-live="polite|assertive" – čtečky oznámí novinky v oblasti; polite čeká na vhodný moment, assertive přeruší čtení.
  • aria-busy="true" – signalizuje načítání; při dokončení nastavte zpět na false.
  • role="status" nebo role="alert" – krátké zprávy o úspěchu či chybě.

Skrytí a prezentace: aria-hidden, inert a správa fokusu

  • aria-hidden="true" odstraní prvek ze stromu přístupnosti, ale neblokuje fokus. Při modálních oknech preferujte inert na okolních prvcích, aby se zablokovala interakce i fokus.
  • Při otevření dialogu přesuňte fokus dovnitř a po zavření vraťte na spouštěč.
  • Skryté dekorace (SVG, ikonové fonty) označte aria-hidden="true" nebo role="img" aria-label="..." s významem.

Obrázky a grafika: role=“img“, alt a komplexní vizualizace

  • U <img> používejte atribut alt. U dekorativní grafiky zvolte prázdný alt="" a zvažte aria-hidden="true".
  • Pro nestandardní grafiku (SVG, canvas) použijte role="img" a název přes aria-label nebo aria-labelledby.
  • Komplexní grafy zpřístupněte krátkým názvem a delším popisem vázaným přes aria-describedby, případně nabídněte datovou tabulku.

Formuláře: chyby, nápovědy a povinná pole

  • Propojte label s polem přes <label for="id"> a id. Pokud label chybí, použijte aria-label.
  • Nápovědu vážte přes aria-describedby="id-popisu".
  • Chyby signalizujte atributem aria-invalid="true" a dynamickou chybovou hláškou v oblasti s role="alert" nebo aria-live.
  • Povinnost pole indikujte vizuálně i programově přes aria-required="true" (u vlastních widgetů).

Dialogy a upozornění: role=“dialog“ a role=“alertdialog“

  • Kontejner má role="dialog" a název přes aria-labelledby (nebo aria-label).
  • U kritických potvrzení použijte role="alertdialog" (silnější zaměření pozornosti).
  • Zablokujte pozadí (inert nebo „focus trap“) a zajistěte klávesu Escape pro zavření.

Navigační prvky: breadcrumbs, pagination, skip links

  • Označte drobečkovou navigaci nav s aria-label="Drobečková navigace" nebo odpovídajícím jazykovým štítkem; odkazy uvnitř seznamu.
  • Paginaci označte nav s aria-label="Stránkování"; aktuální stránka má aria-current="page".
  • Odkaz „Skip to content“ umístěte na začátek a cílový prvek označte id; hlavní obsah má role="main" nebo <main>.

Tabulky, seznamy a struktury: respektujte nativní sémantiku

Pro datové tabulky používejte <table> s <thead>, <tbody>, <th scope="col|row">. Vyhýbejte se ručnímu skládání tabulek z div s ARIA rolemi, pokud to není nezbytné.

ARIA a výkon LLM/SEO: proč to prospívá AIO/AEO

  • Jednoznačná struktura. Landmarky a správná jména prvků zlepšují pochopení informační architektury modely a crawlery.
  • Přesné vztahy. Vztahy aria-labelledby/aria-describedby doplňují kontext (např. u tlačítek, panelů, záložek), což pomáhá extrahovat smysluplné odpovědi.
  • Bohaté stavy UI. Správně aktualizované stavy (aria-expanded, aria-selected) vedou k lepšímu pochopení interaktivity a obsahové viditelnosti.
  • Snížená chybovost parsování. Konzistentní ARIA redukuje šum a anomálie v datech používaných pro indexaci a trénink.

Antivzory: čemu se vyhnout

  • Falešné tlačítko z div s role="button" bez podpory Enter/Space a bez tabindex.
  • Konflikt role a elementu. Například <button role="link"> mate čtečky; použijte správný element.
  • Nesprávné živé oblasti. Zbytečné aria-live="assertive" ruší uživatele.
  • Skrytí obsahu pouze vizuálně. display:none bez ohledu na stav ARIA může čtečku zmást; slaďte vizuální a přístupový stav.
  • Neplatné reference. aria-labelledby="neexistuje" nebo duplicitní id.

Testování a validace: praktický postup

  1. Rychlý audit klávesnicí. Proklikejte celé rozhraní pouze s Tab/Shift+Tab, Enter, Space, šipkami. Fokus musí být viditelný.
  2. Semantická kontrola. Ověřte landmarky (banner, navigation, main, complementary, contentinfo, search).
  3. Stavy v akci. Sledujte, zda se aria-expanded, aria-selected, aria-busy při interakci mění.
  4. Automatizované nástroje. Spusťte lintry a audity (např. axe, Lighthouse, HTML validator) a opravte chyby s vysokou prioritou.
  5. Čtečka obrazovky. Otestujte alespoň v jednom prostředí (NVDA/JAWS/VoiceOver) základní scénáře.

Mini-vzory: zhuštěné příklady

Rozbalovací menu (disclosure):

<button aria-expanded="false" aria-controls="sekce-menu" id="tlacitko-menu">Menu</button>

<div id="sekce-menu" role="region" aria-labelledby="tlacitko-menu" hidden>...navigace...</div>

Při otevření odstraňte hidden a nastavte aria-expanded="true".

Záložky (tabs):

<div role="tablist" aria-label="Sekce">
  <button role="tab" id="tab-1" aria-controls="panel-1" aria-selected="true">Přehled</button>
  <button role="tab" id="tab-2" aria-controls="panel-2" aria-selected="false">Detaily</button>
</div>

<section role="tabpanel" id="panel-1" aria-labelledby="tab-1">...</section>
<section role="tabpanel" id="panel-2" aria-labelledby="tab-2" hidden>...</section>

Mezijazyčnost a lokalizace

  • Nastavte jazyk dokumentu pomocí <html lang="sk">; čtečky podle toho volí syntézu řeči.
  • ARIA štítky pište v jazyce obsahu. U vícejazyčných sekcí používejte lang na vnořených prvcích.

ARIA a design systém: udržitelná implementace

  • Zaveďte knihovnu komponent s jednotnou sémantikou (role, stavy, názvy, klávesnice).
  • Každý komponent dokumentujte: jaké ARIA atributy používá, kdy a jak se mění, jaké má klávesové zkratky.
  • Přidejte unit/e2e testy na stavy a dostupnost (fokus, tab order,