Dostępność
Dostępność
Personel techniczny pracuje w rękawiczkach, na starych myszach, przy rzutniku i w piwnicy bez zasięgu. Klawiatura bywa jedyną drogą, a kolor bywa niewidoczny. Cel: WCAG 2.2 na poziomie AA.
- Stan rozdziału:
- gotowe
Cztery zasady
- Kolor nigdy nie jest jedynym nośnikiem informacji. Status ma słowo i ikonę; brak wpisów ma paski; odnośnik w tekście ma podkreślenie; błąd ma ikonę i
role="alert". Sprawdzamy każdy ekran w skali szarości. - Wszystko da się zrobić z klawiatury, w kolejności czytania, z widocznym ogniskiem.
- Kontrast co najmniej 4,5:1 dla tekstu i 3:1 dla grafiki i obrysów. Liczony, nie zakładany. Tabela w Kolorze.
- Ruch jest opcją.
prefers-reduced-motion: reducewyłącza wszystko, a strona i tak jest w pełni czytelna.
Progi kontrastu
| Co | Próg | Kryterium | W Kanonie |
|---|---|---|---|
| Tekst zwykły (poniżej 24 px, poniżej 19 px pogrubionego) | 4,5:1 | SC 1.4.3 AA | Atrament na papierze 16,73:1, tekst pomocniczy na papierze 5,46:1, biel na fiolecie 5,92:1. |
| Tekst duży (od 24 px, od 19 px pogrubionego) | 3:1 | SC 1.4.3 AA | Nagłówki w atramencie: bez problemu. Nagłówek w fiolecie na papierze 5,87:1. |
| Grafika informacyjna i obrysy elementów (ikona, obrys pola, obrys ogniska, kropka stanu) | 3:1 | SC 1.4.11 AA | Fiolet jako obrys ogniska: 5,87:1 na papierze, 5,43:1 na tle neutralnym. Turkus jako kropka na bieli: 1,80:1, poniżej progu, dlatego kropka turkusowa nigdy nie jest jedynym nośnikiem i zawsze ma słowo obok. |
| Tekst na turkusie | 4,5:1 | SC 1.4.3 | Tylko atrament (9,28:1). Biel na turkusie 1,82:1 jest zakazana. |
Klawiatura
| Element | Tab | Enter / Spacja | Escape | Strzałki |
|---|---|---|---|---|
| Przycisk | dostaje ognisko | uruchamia | nic | nic |
| Odnośnik (także w kształcie przycisku) | dostaje ognisko | Enter otwiera, Spacja przewija stronę | nic | nic |
| Pole | dostaje ognisko | Enter wysyła formularz | nic | kursor w tekście |
| Zakładki filtrów (odnośniki) | każda po kolei | Enter otwiera | nic | nic (to nie jest tablist) |
| Menu podręczne | na wyzwalacz | otwiera; w menu uruchamia pozycję | zamyka i wraca na wyzwalacz | góra / dół po pozycjach |
| Szuflada nawigacji (telefon) | na przycisk „Otwórz menu” | otwiera | zamyka (do zrobienia w aplikacji) | nic |
| Tabela | po odnośnikach i przyciskach w komórkach | jak wyżej | nic | nic; komórki nie są interaktywne |
Spis treści Kanonu na telefonie (details) | na „Spis treści” | rozwija i zwija | nic | nic |
- Ognisko jest widoczne: obrys 2 px fioletu z odstępem 3 px, ten sam wszędzie, przez
:focus-visible. Nie ukrywamy gooutline: nonebez zamiennika. - Kolejność Tab to kolejność czytania. Bez
tabindexwiększego niż zero. Element przesunięty poza ekran (zamknięta szuflada) jest teżvisibility: hidden, żeby nie łapał ogniska. - Odnośnik pomijający („Przejdź do treści”) jest pierwszym elementem strony i pojawia się przy ognisku.
- Pułapka ogniska tylko w modalu i menu, z Escape jako wyjściem. Aplikacja ma to z React Aria; własna implementacja kończy się menu, którego nie da się zamknąć bez myszy.
- Cel dotyku co najmniej 24 na 24 px (SC 2.5.8), a w praktyce 40 px dla przycisków, bo rękawiczka.
Czytnik ekranu i struktura
- Jeden
h1na stronę, nagłówki bez przeskakiwania poziomów. Karta ma nagłówekh2doh4zależnie od miejsca. - Punkty orientacyjne:
header,navzaria-label,main,aside,footer. Kanon ma dwie nawigacje (spis treści i sąsiednie strony), każda nazwana. - Tabela ma
caption(może być ukryty klasąsr-only) ith scope="col". - Ikona dekoracyjna ma
aria-hidden="true". Ikona bez tekstu obok (przycisk zamknięcia) maaria-labelz czasownikiem. - Logo jako obraz ma
role="img"iaria-label="MedPass". Logo dekoracyjne (przykłady zakazów) maaria-hidden. - Aktywna strona w nawigacji ma
aria-current="page". Aktywna zakładka filtra tak samo. - Błąd formularza ma
role="alert"i jest powiązany z polem przezaria-describedby. Pole z błędem maaria-invalid="true". - Język dokumentu
lang="pl". Fragmenty w innym języku (cytat z MDCG) dostałybylang="en".
Teksty alternatywne
| Obraz | Alt | Uwaga |
|---|---|---|
| Logo w nagłówku strony | „MedPass” (na odnośniku: „MedPass, strona główna”) | Nie „logo MedPass”; czytnik sam mówi „obraz”. |
| Symbol w nawigacji aplikacji | „MedPass” | Obok stoi nazwa organizacji jako tekst. |
| Kod QR na etykiecie | „Kod QR: otwiera kartę urządzenia MP-0241” | Z identyfikatorem, bo bez niego etykieta na wydruku jest anonimowa. |
| Zdjęcie w protokole | Opis wpisany przez serwisanta, np. „Pęknięta obudowa przy złączu zasilania” | Pole opisu jest częścią formularza załącznika, nie opcją. |
| Ilustracja marketingowa | „Serwisant skanuje telefonem kod QR na aparacie” | Czynność, nie nastrój. |
| Ikona przy słowie, kropka stanu, paski | pusty (aria-hidden) | Znaczenie niesie słowo obok. |
| Zrzut ekranu w dokumentacji | Co pokazuje i co jest ważne: „Rejestr z trzema urządzeniami po terminie na górze listy” | Nie „zrzut ekranu”. |
Ruch
prefers-reduced-motion: reduce wyłącza przejścia, animacje i płynne przewijanie w Kanonie (theme.css) i w aplikacji (globals.css). Elementy stoją od razu w pozycji końcowej. Nic nie miga, nic nie pulsuje automatycznie. Kółko ładowania przy ograniczeniu ruchu staje się statycznym wskaźnikiem z tekstem. Szczegóły: Ruch.
Bez JavaScriptu
Kanon nie ma ani jednego skryptu po stronie klienta. Spis treści na telefonie to details, nawigacja to odnośniki, przykłady to HTML i CSS. W aplikacji: rejestr, filtry i zakładki działają jako odnośniki bez skryptu; formularze i menu wymagają skryptu, ale stan bez skryptu jest czytelny (tabela widoczna, formularz wysyłalny). Strona marketingowa: zero skryptów poza wariantem roboczym.
Druk
Kontrola dostaje papier albo PDF, nie ekran. W druku znika nawigacja (data-bez-druku), zostaje dokument: czarny tekst na bieli, każdy paszport od nowej strony, wiersz tabeli i wpis historii nie rozjeżdżają się między stronami. Wszystkie stany są czytelne bez koloru, bo mają słowo. To jest test, który przechodzi każdy nowy komponent: wydrukuj w skali szarości i sprawdź, czy wiadomo, co znaczy.
Jak sprawdzamy
- Kontrasty: liczone przy budowaniu Kanonu z tokenów (
src/tokens/kontrast.ts). Nowa para kolorów trafia dokontrasty.tsi od razu widać wynik. - Klawiatura: przejście całej strony klawiszem Tab, bez myszy, przed każdym wdrożeniem nowego komponentu.
- Skala szarości: podgląd w trybie druku albo filtr
grayscale(1)nahtmlw narzędziach przeglądarki. - Ograniczenie ruchu: ustawienie systemowe włączone, strona ma wyglądać na skończoną, nie zepsutą.
- Telefon 390 px: strona nie przewija się w bok, cele dotyku mają co najmniej 40 px, tabela przewija się w pojemniku.
- Czytnik ekranu: VoiceOver na macOS albo NVDA, przejście przez nagłówki (klawisz H) i punkty orientacyjne.