ARIA: Atributy přístupnosti v HTML kódu

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

WAI-ARIA (Accessible Rich Internet Applications) je sada atributů HTML definovaná konzorciem W3C, která doplňuje sémantiku a interakce webových komponent tak, aby byly přístupné uživatelům asistivních technologií (čtečky obrazovky, alternativní vstupy). ARIA nevytváří vizuální prvky, ale „sděluje“ strojům, co prvky jsou a co právě dělají. V době aplikací typu 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 porozumět struktuře a stavům 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 jej. ARIA je doplněk, nikoliv 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“. Nesprávné 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 komponenty.

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) – měnící se stavy během interakcí.

Landmark role: kostra stránky pro rychlou navigaci

Landmarky umožňují přeskočení na dané části stránky pomocí čteček obrazovky a rovněž pomáhají vyhledávačům a LLM pochopit rozvržení:

  • 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" – patička (na <footer>).
  • role="search" – vyhledávací formulář.

Používejte nativní prvky (header, nav, main, aside, footer), které už landmark roli implicitně obsahují. 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ý název. 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ňující 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

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

  • Button (tlačítko): role="button", aktivace Enter i Space, fokus přes tabindex="0" (pokud to není nativní <button>).
  • Disclosure/Accordion (zobrazovací prvek/záložky): ovládací prvek s aria-expanded="true|false" a cílový obsah s aria-hidden nebo řízeným zobrazením; propojení přes aria-controls.
  • Tabs (záložky): 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í; nastavte zpět na false, když je obsah připraven.
  • 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. U modalů preferujte inert na okolním obsahu, aby se zablokovala interakce a 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

  • Pro <img> používejte atribut alt. U dekorativní grafiky zvolte prázdný alt="" a zvažte aria-hidden="true".
  • U nestandardní grafiky (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 navázaným pomocí 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 připojte přes aria-describedby="id-popisu".
  • Chyby signalizujte 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“

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

Navigační prvky: breadcrumbs, stránkování, skip links

  • Označte drobečkovou navigaci elementem nav s aria-label="Drobečková navigace" (nebo podle jazyka); odkazy uvnitř v seznamu.
  • Stránkování označte nav s aria-label="Stránkování"; aktuální stránka má aria-current="page".
  • Odkaz „Přeskočit na obsah“ umístěte na začátek a cílový prvek označte id; hlavní obsah by měl mít role="main" nebo <main>.

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

Pro datové tabulky používejte <table> s <thead>, <tbody> a <th scope="col|row">. Vyhýbejte se ručnímu sestavová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é názvy prvků zlepšují porozumění informační architektuře 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 viditelnosti obsahu.
  • Nižší 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ř. <button role="link"> mate čtečky; použijte správný element.
  • Chybné živé oblasti. Zbytečné aria-live="assertive" ruší uživatele.
  • Skrytí obsahu pouze vizuálně. display:none bez ohledu na stav ARIA může zmást čtečku; sladě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é uživatelské rozhraní pouze pomocí Tab/Shift+Tab, Enter, Space, šipek. 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

  • Jazyk dokumentu nastavte přes <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é