Vytvářejte přístupná a uživatelsky přívětivá rozhraní s kartami. Naučte se osvědčené postupy pro klávesnicovou navigaci, role ARIA a robustní správu fokusu.
Dokonalé ovládání rozhraní s kartami: Hloubkový pohled na klávesnicovou navigaci a správu fokusu
Rozhraní s kartami jsou základním kamenem moderního webového designu. Od produktových stránek a uživatelských panelů až po složité webové aplikace poskytují elegantní řešení pro organizaci obsahu a zjednodušení uživatelského rozhraní. Ačkoliv se mohou na první pohled zdát jednoduché, vytvoření skutečně efektivní a přístupné komponenty s kartami vyžaduje hluboké porozumění klávesnicové navigaci a pečlivou správu fokusu. Špatně implementované rozhraní s kartami se může stát nepřekonatelnou bariérou pro uživatele, kteří se spoléhají na klávesnici nebo asistenční technologie, a efektivně je tak odříznout od vašeho obsahu.
Tento komplexní průvodce je určen pro webové vývojáře, UI/UX designéry a zastánce přístupnosti, kteří chtějí jít za hranice základů. Prozkoumáme mezinárodně uznávané vzory pro interakci pomocí klávesnice, klíčovou roli ARIA (Accessible Rich Internet Applications) při poskytování sémantického kontextu a propracované techniky pro správu fokusu, které vytvářejí plynulý a intuitivní uživatelský zážitek pro všechny, bez ohledu na jejich polohu nebo způsob interakce s webem.
Anatomie rozhraní s kartami: Klíčové komponenty
Než se ponoříme do mechaniky, je nezbytné stanovit společnou terminologii založenou na WAI-ARIA Authoring Practices. Standardní komponenta s kartami se skládá ze tří hlavních prvků:
- Seznam karet (`role="tablist"`): Toto je kontejnerový prvek, který obsahuje sadu karet. Funguje jako primární widget, se kterým uživatelé interagují pro přepínání mezi různými obsahovými panely.
- Karta (`role="tab"`): Jednotlivý klikatelný prvek v seznamu karet. Po aktivaci zobrazí svůj přidružený obsahový panel. Vizuálně je to samotná „karta“.
- Panel karty (`role="tabpanel"`): Kontejner pro obsah spojený s konkrétní kartou. V daný okamžik je viditelný pouze jeden panel – ten, který odpovídá aktuálně aktivní kartě.
Pochopení této struktury je prvním krokem k vytvoření komponenty, která je nejen vizuálně soudržná, ale také sémanticky srozumitelná pro asistenční technologie, jako jsou čtečky obrazovky.
Principy bezchybné klávesnicové navigace
Pro uživatele s myší je interakce s kartami jednoduchá: kliknou na kartu, kterou chtějí vidět. Pro uživatele pouze s klávesnicí musí být zážitek stejně intuitivní. WAI-ARIA Authoring Practices poskytují robustní a standardizovaný model pro interakci pomocí klávesnice, který uživatelé asistenčních technologií očekávají.
Navigace v seznamu karet (`role="tablist"`)
Primární interakce probíhá v rámci seznamu karet. Cílem je umožnit uživatelům efektivně procházet a vybírat karty, aniž by museli procházet každý interaktivní prvek na stránce.
- Klávesa `Tab`: Toto je vstupní a výstupní bod. Když uživatel stiskne `Tab`, fokus by se měl přesunout *do* seznamu karet a přistát na aktuálně aktivní kartě. Další stisknutí `Tab` by mělo přesunout fokus *ze* seznamu karet na další fokusovatelný prvek na stránce (nebo do aktivního panelu karty, v závislosti na vašem designu). Klíčové je, že celý widget seznamu karet by měl představovat jedinou zastávku v celkovém pořadí procházení stránky pomocí klávesy Tab.
- Šipkové klávesy (`Vlevo/Vpravo` nebo `Nahoru/Dolů`): Jakmile je fokus uvnitř seznamu karet, pro navigaci se používají šipkové klávesy.
- U horizontálního seznamu karet přesune klávesa `Šipka vpravo` fokus na další kartu a klávesa `Šipka vlevo` na předchozí kartu.
- U vertikálního seznamu karet přesune klávesa `Šipka dolů` fokus na další kartu a klávesa `Šipka nahoru` na předchozí kartu.
- Klávesy `Home` a `End`: Pro efektivitu v seznamech s mnoha kartami poskytují tyto klávesy zkratky.
- `Home`: Přesune fokus na první kartu v seznamu.
- `End`: Přesune fokus na poslední kartu v seznamu.
Modely aktivace: Automatická vs. Manuální
Kdy by se měl zobrazit odpovídající panel, když uživatel naviguje mezi kartami pomocí šipkových kláves? Existují dva standardní modely:
- Automatická aktivace: Jakmile karta získá fokus pomocí šipkové klávesy, její přidružený panel se zobrazí. Toto je nejběžnější vzor a je obecně upřednostňován pro svou okamžitost. Snižuje počet stisknutí kláves potřebných k zobrazení obsahu.
- Manuální aktivace: Přesunutí fokusu pomocí šipkových kláves pouze zvýrazní kartu. Uživatel musí poté stisknout `Enter` nebo `Mezerník` k aktivaci karty a zobrazení jejího panelu. Tento model může být užitečný, když panely karet obsahují velké množství obsahu nebo spouštějí síťové požadavky, protože zabraňuje zbytečnému načítání obsahu, zatímco uživatel pouze prochází možnosti karet.
Vaše volba modelu aktivace by měla být založena na obsahu a kontextu vašeho rozhraní. Ať už si vyberete kterýkoli, buďte konzistentní v celé vaší aplikaci.
Dokonalá správa fokusu: Nezpívaný hrdina použitelnosti
Efektivní správa fokusu je to, co odlišuje neohrabané rozhraní od plynulého. Jde o programové řízení toho, kde se nachází fokus uživatele, a zajištění logické a předvídatelné cesty komponentou.
Technika „Roving `tabindex`“
Technika „roving `tabindex`“ je základním kamenem klávesnicové navigace v komponentách, jako jsou seznamy karet. Cílem je, aby celý widget fungoval jako jediná zastávka pro klávesu `Tab`.
Funguje to takto:
- Aktuálně aktivní prvek karty dostane `tabindex="0"`. Tím se stane součástí přirozeného pořadí procházení a umožní mu přijmout fokus, když se uživatel dostane do komponenty pomocí klávesy Tab.
- Všechny ostatní neaktivní prvky karet dostanou `tabindex="-1"`. Tím jsou odstraněny z přirozeného pořadí procházení, takže uživatel nemusí stisknout `Tab` pro každou z nich. Stále je však lze fokusovat programově, což děláme při navigaci šipkovými klávesami.
Když uživatel stiskne šipkovou klávesu pro přesun z Karty A na Kartu B:
- Logika v JavaScriptu aktualizuje Kartu A, aby měla `tabindex="-1"`.
- Poté aktualizuje Kartu B, aby měla `tabindex="0"`.
- Nakonec zavolá `.focus()` na prvku Karty B, aby tam přesunula fokus uživatele.
Tato technika zajišťuje, že bez ohledu na to, kolik karet je v seznamu, komponenta zabírá pouze jednu pozici v celkovém pořadí procházení stránky pomocí klávesy `Tab`.
Fokus uvnitř panelů karet
Jakmile je karta aktivní, kam se přesune fokus dál? Očekávané chování je, že stisknutí `Tab` na aktivním prvku karty přesune fokus na první fokusovatelný prvek *uvnitř* jejího odpovídajícího panelu. Pokud panel karty nemá žádné fokusovatelné prvky, stisknutí `Tab` by mělo přesunout fokus na další fokusovatelný prvek na stránce *za* seznamem karet.
Podobně, když je uživatel fokusován na posledním fokusovatelném prvku uvnitř panelu karty, stisknutí `Tab` by mělo přesunout fokus z panelu na další fokusovatelný prvek na stránce. Stisknutí `Shift + Tab` na prvním fokusovatelném prvku uvnitř panelu by mělo přesunout fokus zpět na aktivní prvek karty.
Vyhněte se uzamčení fokusu (focus trapping): Rozhraní s kartami není modální dialog. Uživatelé by měli být vždy schopni navigovat do a z komponenty s kartami a jejích panelů pomocí klávesy `Tab`. Neuzamykejte fokus uvnitř komponenty, protože to může být matoucí a frustrující.
Role ARIA: Komunikace sémantiky asistenčním technologiím
Bez ARIA je rozhraní s kartami postavené pomocí prvků `
Základní role a atributy ARIA
- `role="tablist"`: Umístí se na prvek obsahující karty. Oznamuje: „Toto je seznam karet.“
- `aria-label` nebo `aria-labelledby`: Používá se na prvku `tablist` k poskytnutí přístupného názvu, například `aria-label="Kategorie obsahu"`.
- `role="tab"`: Umístí se na každý jednotlivý ovládací prvek karty (často prvek `
- `aria-selected="true"` nebo `"false"`: Kritický atribut stavu na každé `role="tab"`. `"true"` označuje aktuálně aktivní kartu, zatímco `"false"` označuje neaktivní. Tento stav musí být dynamicky aktualizován pomocí JavaScriptu.
- `aria-controls="panel-id"`: Umístí se na každou `role="tab"`, jeho hodnota by měla být `id` prvku `tabpanel`, který ovládá. Tím se vytváří programové propojení mezi ovládacím prvkem a jeho obsahem.
- `role="tabpanel"`: Umístí se na každý prvek obsahového panelu. Oznamuje: „Toto je panel obsahu spojený s kartou.“
- `aria-labelledby="tab-id"`: Umístí se na každý `role="tabpanel"`, jeho hodnota by měla být `id` prvku `role="tab"`, který jej ovládá. Tím se vytváří zpětná asociace, která pomáhá asistenčním technologiím pochopit, která karta panel označuje.
Skrytí neaktivního obsahu
Nestačí jen vizuálně skrýt neaktivní panely karet. Musí být skryty i před asistenčními technologiemi. Nejefektivnějším způsobem, jak toho dosáhnout, je použití atributu `hidden` nebo `display: none;` v CSS. Tím se obsah panelu odstraní ze stromu přístupnosti, což zabrání čtečce obrazovky v ohlašování obsahu, který není aktuálně relevantní.
Praktická implementace: Příklad na vysoké úrovni
Podívejme se na zjednodušenou HTML strukturu, která zahrnuje tyto ARIA role a atributy.
Struktura HTML
<h2 id="tablist-label">Nastavení účtu</h2>
<div role="tablist" aria-labelledby="tablist-label">
<button id="tab-1" type="button" role="tab" aria-selected="true" aria-controls="panel-1" tabindex="0">
Profil
</button>
<button id="tab-2" type="button" role="tab" aria-selected="false" aria-controls="panel-2" tabindex="-1">
Heslo
</button>
<button id="tab-3" type="button" role="tab" aria-selected="false" aria-controls="panel-3" tabindex="-1">
Oznámení
</button>
</div>
<div id="panel-1" role="tabpanel" aria-labelledby="tab-1" tabindex="0">
<p>Obsah pro panel Profil...</p>
</div>
<div id="panel-2" role="tabpanel" aria-labelledby="tab-2" tabindex="0" hidden>
<p>Obsah pro panel Heslo...</p>
</div>
<div id="panel-3" role="tabpanel" aria-labelledby="tab-3" tabindex="0" hidden>
<p>Obsah pro panel Oznámení...</p>
</div>
Logika JavaScriptu (pseudokód)
Váš JavaScript by byl zodpovědný za naslouchání událostem klávesnice na `tablist` a odpovídající aktualizaci atributů.
const tablist = document.querySelector('[role="tablist"]');
const tabs = tablist.querySelectorAll('[role="tab"]');
tablist.addEventListener('keydown', (e) => {
let currentTab = document.activeElement;
let newTab;
if (e.key === 'ArrowRight' || e.key === 'ArrowDown') {
// Najde další kartu v pořadí, v případě potřeby se zacyklí
newTab = getNextTab(currentTab);
} else if (e.key === 'ArrowLeft' || e.key === 'ArrowUp') {
// Najde předchozí kartu v pořadí, v případě potřeby se zacyklí
newTab = getPreviousTab(currentTab);
} else if (e.key === 'Home') {
newTab = tabs[0];
} else if (e.key === 'End') {
newTab = tabs[tabs.length - 1];
}
if (newTab) {
activateTab(newTab);
e.preventDefault(); // Zabrání výchozímu chování prohlížeče pro šipkové klávesy
}
});
function activateTab(tab) {
// Deaktivuje všechny ostatní karty
tabs.forEach(t => {
t.setAttribute('aria-selected', 'false');
t.setAttribute('tabindex', '-1');
document.getElementById(t.getAttribute('aria-controls')).hidden = true;
});
// Aktivuje novou kartu
tab.setAttribute('aria-selected', 'true');
tab.setAttribute('tabindex', '0');
document.getElementById(tab.getAttribute('aria-controls')).hidden = false;
tab.focus();
}
Globální aspekty a osvědčené postupy
Tvorba pro globální publikum vyžaduje přemýšlet za hranice jednoho jazyka nebo kultury. Pokud jde o rozhraní s kartami, nejvýznamnějším aspektem je směr textu.
Podpora jazyků psaných zprava doleva (RTL)
Pro jazyky jako arabština, hebrejština a perština, které se čtou zprava doleva, musí být model klávesnicové navigace zrcadlově obrácen. V kontextu RTL:
- Klávesa `Šipka vpravo` by měla přesunout fokus na předchozí kartu.
- Klávesa `Šipka vlevo` by měla přesunout fokus na následující kartu.
To lze implementovat v JavaScriptu detekcí směru dokumentu (`dir="rtl"`) a odpovídajícím obrácením logiky pro klávesy šipka vlevo a vpravo. Tato zdánlivě malá úprava je klíčová pro poskytnutí intuitivního zážitku milionům uživatelů po celém světě.
Vizuální indikace fokusu
Nestačí, aby byl fokus správně spravován v pozadí; musí být jasně viditelný. Zajistěte, aby vaše fokusované karty a interaktivní prvky v panelech karet měly vysoce viditelný obrys fokusu (např. výrazný kroužek nebo ohraničení). Vyhněte se odstraňování obrysů pomocí `outline: none;`, aniž byste poskytli robustnější a přístupnější alternativu. To je klíčové pro všechny uživatele klávesnice, ale zejména pro ty se slabým zrakem.
Závěr: Tvorba pro inkluzi a použitelnost
Vytvoření skutečně přístupného a uživatelsky přívětivého rozhraní s kartami je cílevědomý proces. Vyžaduje to překročit vizuální design a zabývat se základní strukturou, sémantikou a chováním komponenty. Přijetím standardizovaných vzorů klávesnicové navigace, správnou implementací rolí a atributů ARIA a precizní správou fokusu můžete vytvářet rozhraní, která nejsou jen v souladu s předpisy, ale skutečně intuitivní a posilující pro všechny uživatele.
Pamatujte na tyto klíčové principy:
- Použijte jednu zastávku pro Tab: Využijte techniku „roving `tabindex`“, aby byla celá komponenta navigovatelná pomocí šipkových kláves.
- Komunikujte pomocí ARIA: Použijte `role="tablist"`, `role="tab"` a `role="tabpanel"` spolu s jejich přidruženými vlastnostmi (`aria-selected`, `aria-controls`), abyste poskytli sémantický význam.
- Spravujte fokus logicky: Zajistěte, aby se fokus pohyboval předvídatelně z karty na panel a ven z komponenty.
- Skryjte neaktivní obsah správně: Použijte `hidden` nebo `display: none` k odstranění neaktivních panelů ze stromu přístupnosti.
- Testujte důkladně: Otestujte svou implementaci pouze pomocí klávesnice a s různými čtečkami obrazovky (NVDA, JAWS, VoiceOver), abyste se ujistili, že funguje podle očekávání pro všechny.
Investováním do těchto detailů přispíváme k inkluzivnějšímu webu – takovému, kde jsou komplexní informace přístupné všem, bez ohledu na to, jak se pohybují digitálním světem.