tab
Oznacza element jako jeden tab w interfejsie z kartami. Tab MUSI znajdować się wewnątrz tablist i POWINIEN wskazywać powiązany tabpanel przez aria-controls. Nie istnieje natywny element HTML dla kart — wzorzec ten oparty jest wyłącznie na ARIA.
Kiedy używać
Dla jednej karty w poziomym lub pionowym pasku kart. Tab MUSI być bezpośrednim dzieckiem elementu role="tablist" (lub należeć do niego przez aria-owns). Każdy tab MUSI wskazywać powiązany panel przez aria-controls="<tabpanel-id>". Zwrotny aria-labelledby umieszcza się na panelu i wskazuje z powrotem na tab.
Karty to wzorzec aplikacyjny. Jeśli „karty” są tak naprawdę nawigacją między oddzielnymi stronami, użyj <nav> z łączami <a> — zmiana URL sprawia, że wzorzec kart jest nieodpowiedni.
Sam tab to zazwyczaj <button>. Semantyka przycisku łączy się naturalnie z role="tab", a obsługa fokusu i aktywacji jest zapewniona bezpłatnie.
Kontrakt klawiatury i fokusu
Zgodnie z wzorcem APG dla kart:
- Tab przenosi fokus do tablist, na aktywną kartę. Tab przenosi fokus NA ZEWNĄTRZ do kolejnego elementu (zazwyczaj do tabpanel, jeśli ma
tabindex="0"). - Strzałki Lewo/Prawo (lub Góra/Dół dla pionowych tablist) przesuwają fokus między kartami.
- Home / End przeskakują do pierwszej / ostatniej karty.
- Aktywacja może być automatyczna (fokus = wybór) lub ręczna (Space/Enter do wyboru). Wybierz tryb ręczny, gdy aktywacja karty wyzwala kosztowne operacje.
Stosuj roving tabindex: tylko wybrana karta ma tabindex="0".
Typowe błędy
- Wszystkie karty z
tabindex="0"— Tab przechodzi przez każdą kartę zamiast przez panel. - Brak
aria-controlsłączącego kartę z tabpanel. aria-selected="true"na więcej niż jednej karcie.- Karty zrealizowane z
<a href="#section">— fragment URL ulega zmianie, przycisk „wstecz” nawiguje między kartami i wzorzec się rozpada. - Brak zarządzania fokusem po aktywacji: kliknięcie karty aktualizuje panel, ale kolejne naciśnięcie Tab wraca do nagłówka strony zamiast do panelu.
Przykład
<div role="tablist" aria-label="Account settings">
<button role="tab" id="t-profile" aria-selected="true" aria-controls="p-profile" tabindex="0">Profile</button>
<button role="tab" id="t-billing" aria-selected="false" aria-controls="p-billing" tabindex="-1">Billing</button>
<button role="tab" id="t-security" aria-selected="false" aria-controls="p-security" tabindex="-1">Security</button>
</div>
<section role="tabpanel" id="p-profile" aria-labelledby="t-profile" tabindex="0">…</section>
<section role="tabpanel" id="p-billing" aria-labelledby="t-billing" hidden>…</section>
<section role="tabpanel" id="p-security" aria-labelledby="t-security" hidden>…</section>