html, javascript, blokada Tabulatora
keydown
, sprawdzić czy event.key === "Tab"
i wywołać event.preventDefault()
. • keydown
+ preventDefault()
blokuje Tab w momencie naciśnięcia.
• tabindex="-1"
wyklucza element z sekwencji Tab bez blokady klawisza.
• Focus-trap utrzymuje nawigację w obrębie kontenera (np. modala).
• Rozwiązania komercyjnych bibliotek (np. focus-trap, tabbable, @floating-ui) upraszczają implementację i spełniają WCAG 2.2.
Klawisz Tab przenosi fokus pomiędzy elementami interaktywnymi (a, button, input, textarea, select, [tabindex≥0]). Shift + Tab
nawiguje wstecz. Mechanizm ten jest krytyczny dla dostępności stron.
document.addEventListener('keydown', e=>{
if (e.key === 'Tab') { e.preventDefault(); }
}, {capture:true});
const blocked = document.querySelector('#blocked');
blocked.addEventListener('keydown', e=>{
if (e.key === 'Tab') e.preventDefault();
});
function trapFocus(container){
const focusables = container.querySelectorAll(
'button,[href],input,select,textarea,[tabindex]:not([tabindex="-1"])'
);
const first = focusables[0], last = focusables[focusables.length-1];
container.addEventListener('keydown', e=>{
if(e.key!=='Tab') return;
if(e.shiftKey && document.activeElement===first){e.preventDefault(); last.focus();}
if(!e.shiftKey && document.activeElement===last){e.preventDefault(); first.focus();}
});
}
trapFocus(document.querySelector('#modal'));
<button tabindex="-1">Pomijany przy Tab</button>
Tabulator domyślnie przechwytuje Tab do poruszania się po komórkach.
Jeżeli potrzebna jest pełna blokada wewnątrz siatki:
table.element.addEventListener('keydown', e=>{
if(e.key==="Tab") e.preventDefault();
});
Jeżeli chcemy, aby Tab opuszczał siatkę dopiero na ostatniej komórce, używamy hook-a cellEditing
+ cellEdited
i sterujemy tabindex
/ focus()
.
• WCAG 2.2 (2023) wymaga możliwości obsługi całości interfejsu klawiaturą.
• EN 301 549 / Ustawy o dostępności cyfrowej (Polska) – blokada Tab bez alternatywy = niezgodność.
• W modalach focus-trap jest wymogiem a nie problemem – poprawia a11y.
• Dla edytorów kodu zapewnij skróty jak Ctrl+M
do przełączania trybu „fokus w edytorze / fokus w UI”.
• Atrybut inert
(Chromium 102+, Safari 15.4+) – pozwala programowo wyłączyć wszystkie interakcje (w tym Tab) poza wybranym kontenerem:
modal.show(); document.body.querySelectorAll(':not(#modal)').forEach(el=>el.inert=true);
• Element <dialog>
z metodą showModal()
w Chrome 117+ automatycznie zakłada focus-trap.
• CSS :focus-visible
upraszcza stylowanie elementów obsługiwanych klawiaturą.
• Biblioteki gotowe: focus-trap
, react-aria
, @floating-ui/react
– implementują WCAG-compliant focus management.
• W siatkach danych trendem jest „keyboard navigation mode” (Tab, strzałki, Esc) – Tabulator od v5.5 wspiera konfigurację keybindings.tabNavigation
.
keydown
vs keyup
: tylko keydown
umożliwia skuteczne preventDefault()
. capture:true
w addEventListener
gwarantuje, że nasłuchiwacz wywoła się zanim biblioteki (np. React) przetworzą zdarzenie. stopPropagation()
blokuje przekazanie zdarzenia w górę drzewa DOM, ale nie jest konieczne, gdy wykonamy preventDefault()
dla samego Tab.tabindex="-1"
i focus()
zamiast blokady, gdy chcesz przenieść fokus warunkowo. axe DevTools
, Lighthouse – audyty wykryją błędy fokusu. event.keyCode
) dodaj sprawdzenie e.which === 9
.inert
nie jest jeszcze wspierany w Firefox (czerwiec 2024) – potrzebny polyfill. • Porównanie bibliotek focus-trap
vs tabbable
.
• Badania UX nad zachowaniem klawisza Tab w edytorach kodu on-line.
• Monitorowanie implementacji inert
w Firefox Nightly.
• Analiza różnic WCAG 2.2 Success Criterion 2.4.11 (Focus Not Obscured) – wpływ na modale.
Blokada lub kontrola klawisza Tab w HTML/JavaScript sprowadza się technicznie do keydown
+ preventDefault()
, jednak kluczowe jest, by robić to selektywnie i w sposób dostępny. W modalach stosujemy focus-trap, w siatkach danych (np. Tabulator.js) konfigurujemy własne reguły nawigacji, a w pozostałych przypadkach preferujemy zarządzanie tabindex
i atrybutem inert
. Zawsze testuj z czytnikami ekranu i według WCAG, aby uniknąć wykluczenia użytkowników.