Przejdź do głównej zawartości

18. Accessibility w React

Accessibility (a11y) w React

Dostępność (a11y) to projektowanie aplikacji tak, by mogły z nich korzystać osoby z niepełnosprawnościami (wzroku, słuchu, ruchową). W praktyce: semantyczny HTML, ARIA atrybuty, nawigacja klawiaturą. Bonus: dostępne aplikacje są lepiej indeksowane przez Google.

  1. Dlaczego dostępność? — Prawo (WCAG), etyka, SEO, 15% populacji z niepełnosprawnościami
  2. Semantyczny HTML?<button> zamiast <div onClick>, <nav>, <main>, <article>
  3. ARIA? — Atrybuty uzupełniające semantykę gdy HTML nie wystarczy
  4. Nawigacja klawiaturą? — Tab, Enter, Escape — każda akcja musi być dostępna bez myszy
  1. Dlaczego a11y? — WCAG, prawo, liczby, SEO
  2. Semantyczny HTML w React<button> nie <div>, nagłówki hierarchicznie
  3. ARIA role i atrybuty — aria-label, aria-expanded, role=“dialog”
  4. Focus management — useRef do przeniesienia focusu w modalach
  5. Kontrast kolorów — WCAG AA: 4.5:1 dla tekstu

Schemat

Przykład struktury HTML przed (pełne <div>) i po (semantyczne <nav>, <main>, <button>, <article>). Pokaż jak czytnik ekranu “widzi” każdą wersję.

Przykład kodu JSX

Modal z poprawnym focus management: gdy się otwiera — focus na pierwszym elemencie, Escape zamyka, po zamknięciu — focus wraca do triggera.

  • Co to jest a11y i WCAG
  • Semantyczny HTML vs div-soup
  • Podstawowe ARIA: aria-label, alt

Forma: 10 slajdów, 10 minut

Ocena: 3.0
// ŹLE: div soup — niewidomy nie wie co to jest
function BadNav() {
return (
<div className="nav">
<div className="nav-item" onClick={goHome}>Strona główna</div>
<div className="nav-item" onClick={goProducts}>Produkty</div>
</div>
);
}
// DOBRZE: semantyczny HTML
function GoodNav() {
return (
<nav aria-label="Nawigacja główna">
<ul>
<li><a href="/">Strona główna</a></li>
<li><a href="/products">Produkty</a></li>
</ul>
</nav>
);
}
function Modal({ isOpen, onClose, title, children }) {
const firstFocusable = useRef(null);
useEffect(() => {
if (isOpen) {
firstFocusable.current?.focus(); // Focus wchodzi do modala
}
}, [isOpen]);
if (!isOpen) return null;
return (
<div
role="dialog"
aria-modal="true"
aria-labelledby="modal-title"
onKeyDown={e => e.key === 'Escape' && onClose()}
>
<h2 id="modal-title">{title}</h2>
<button ref={firstFocusable}>Pierwsze działanie</button>
{children}
<button onClick={onClose}>Zamknij</button>
</div>
);
}

Demo z klawiaturą

Odłóżcie myszkę i spróbujcie użyć Waszej aplikacji tylko Tab + Enter. Jeśli da się — aplikacja jest dostępna. Pokażcie to klasie.

Włącz czytnik ekranu

Windows: Narrator. Mac: VoiceOver (Cmd+F5). Pokażcie jak czytnik “czyta” zarówno złą (div-soup) jak i dobrą (semantyczną) wersję.

Dostępność to nie opcja — to standard!

UE coraz mocniej wymaga dostępności w aplikacjach. Ten temat pokazuje że tworzycie oprogramowanie dla WSZYSTKICH użytkowników!