Kurs HTML i CSS · Moduł 10: Dostępność (a11y)
Testowanie dostępności
W tej lekcji6
Zbudowałeś stronę muzeum zgodnie ze wszystkimi zasadami z tego modułu. Skąd jednak wiesz, że naprawdę działa? Łatwo przeoczyć brakujący alt albo pole bez etykiety, dopóki sam nie przejdziesz strony tak jak inni. Nawet najlepsza wiedza o dostępności nie zastąpi praktycznego testowania. Tak jak archeolodzy systematycznie przeszukują stanowiska wykopaliskowe, tak my musimy systematycznie testować nasze strony pod kątem dostępności, używając różnych narzędzi i metod.
Testy idą od najszybszych do najbardziej wymagających: najpierw automat (Lighthouse lub axe), potem test klawiatury, następnie czytnik ekranowy, a na końcu testy z użytkownikami z niepełnosprawnościami. Każdy etap łapie błędy, których poprzedni nie widzi.
Automatyczne narzędzia
Lighthouse (wbudowany w Chrome DevTools)
Lighthouse to bezpłatne narzędzie Google, które można uruchomić bezpośrednio z Chrome DevTools:
- Otwórz DevTools (F12)
- Przejdź do zakładki "Lighthouse"
- Zaznacz "Accessibility"
- Kliknij "Analyze page load"
Lighthouse sprawdza m.in.:
- Czy obrazy mają tekst alternatywny
- Czy kontrast kolorów jest wystarczający
- Czy elementy formularzy mają etykiety
- Czy strona ma poprawną hierarchię nagłówków
Uwaga: wynik 100 nie oznacza, że strona jest w pełni dostępna. Automat sprawdzi, czy obraz ma alt, ale nie oceni, czy ten alt ma sens - dlatego po nim zawsze przychodzą testy ręczne.
axe DevTools
axe to jedno z najpopularniejszych narzędzi do testowania dostępności - rozszerzenie przeglądarki oparte na silniku axe-core, z którego korzysta też Lighthouse. Każdy problem opisuje w stałym formacie:
1<!-- Wynik testu axe może wyglądać tak: -->
2<!--
3 Violation: Images must have alternate text
4 Element: <img src="pharaoh.jpg">
5 Fix: Add an alt attribute to the image
6 Impact: Critical
7 WCAG: 1.1.1 (Level A)
8-->Raport mówi, co jest źle, jak to naprawić, jak poważny jest problem (Impact) i którego kryterium WCAG dotyczy - tutaj 1.1.1, czyli tekstów alternatywnych.
HTML Validator (W3C)
Poprawny HTML to fundament dostępności, bo czytniki polegają na drzewie elementów zbudowanym z Twojego kodu. Walidator wykryje błędy, które to drzewo psują:
1<!-- Błędy wykrywane przez walidator: -->
2
3<!-- Błąd: Brak atrybutu alt -->
4<img src="photo.jpg">
5
6<!-- Błąd: Zduplikowane ID -->
7<input id="name">
8<label id="name">
9
10<!-- Błąd: Niepoprawne zagnieżdżenie -->
11<p>Tekst <div>w divie</div> w paragrafie</p>Zduplikowane id psuje powiązania for i aria-describedby, a <div> wewnątrz <p> sprawia, że przeglądarka zamyka akapit wcześniej, niż zamierzałeś. Walidator poznasz bliżej w następnym module.
Ręczne testowanie
Test klawiatury
Najprostszy test ręczny: odłóż myszkę i przejdź całą stronę klawiszami Tab, Shift+Tab, Enter i Escape, odhaczając kolejne punkty:
1Checklist nawigacji klawiaturowej:
2[ ] Czy można dotrzeć do każdego interaktywnego elementu Tabem?
3[ ] Czy kolejność focusu jest logiczna?
4[ ] Czy focus jest zawsze widoczny?
5[ ] Czy modalne okna dialogowe przechwytują focus?
6[ ] Czy można zamknąć modal klawiszem Escape?
7[ ] Czy skip link działa poprawnie?
8[ ] Czy formularze można wysłać Enterem?
9[ ] Czy rozwijane menu można nawigować strzałkami?Test trwa kilka minut, a wykrywa to, czego automat nie zobaczy, np. focus znikający w ukrytym menu. Wyślij też pusty formularz i sprawdź, czy komunikaty prowadzą Cię do błędnych pól.
Test czytnika ekranowego
Czytnik ekranowy to jedyny sposób, by usłyszeć stronę tak, jak słyszy ją osoba niewidoma. Popularne czytniki ekranowe:
- NVDA (Windows, bezpłatny) - www.nvaccess.org
- VoiceOver (macOS/iOS, wbudowany) - Cmd + F5
- JAWS (Windows, płatny) - profesjonalny standard
- TalkBack (Android, wbudowany)
Na początek wystarczy VoiceOver lub darmowy NVDA - posłuchaj, czy pola mają sensowne nazwy. Ostatnim, najcenniejszym etapem są testy z użytkownikami z niepełnosprawnościami - nikt nie zna ich potrzeb lepiej niż oni sami.
Test powiększania
Osoby słabowidzące powiększają stronę, zamiast mrużyć oczy nad drobnym tekstem. Powiększysz ją skrótem Ctrl i + (Cmd i + na Macu):
1Checklist testu powiększania:
2[ ] Powiększ stronę do 200% - czy cała treść jest widoczna?
3[ ] Powiększ do 400% - czy strona nadal działa?
4[ ] Czy tekst się nie ucina i nie nakłada?
5[ ] Czy scrollowanie jest tylko w jednym kierunku?Progi pochodzą z WCAG: kryterium 1.4.4 wymaga powiększenia tekstu do 200% bez utraty treści, a 1.4.10 - braku przewijania w dwóch kierunkach przy szerokości 320 pikseli CSS, czyli przy 400% na ekranie 1280px.
Chrome DevTools - Accessibility
Panel Accessibility
DevTools pokażą, jak przeglądarka "tłumaczy" element dla czytnika. Zaznacz element w panelu Elements i otwórz kartę Accessibility:
1Chrome DevTools > Elements > Accessibility:
2- Name: "Zamknij" (z aria-label)
3- Role: button
4- Focusable: true
5- Description: "Zamknij okno dialogowe"Name to dostępna nazwa elementu, a Role mówi, czym on jest. Puste Name oznacza, że czytnik nie ma czego odczytać - właśnie znalazłeś błąd.
Symulacja wad wzroku
DevTools potrafią też pokazać stronę oczami osoby z zaburzeniami widzenia. Chrome DevTools > Rendering > Emulate vision deficiencies:
- Protanopia (brak czerwonego)
- Deuteranopia (brak zielonego)
- Tritanopia (brak niebieskiego)
- Blurred vision (nieostre widzenie)
Panel Rendering otworzysz z menu DevTools (More tools). Włącz protanopię i zobacz, czy czerwona ramka błędu nadal się wyróżnia.
Inspekcja kontrastu
Kontrast sprawdzisz bez wychodzenia z DevTools. W karcie Styles kliknij kwadracik koloru obok właściwości color:
1Chrome DevTools > Elements > Styles:
2- Kliknij kwadracik koloru przy właściwości color
3- Selektor kolorów pokaże Contrast ratio
4- Znacznik przy AA = tekst spełnia próg 4.5:1
5- Znacznik przy AAA = spełnia też próg 7:1
6- Brak znacznika = kontrast za niskiKolor możesz tam przesuwać, aż kontrast osiągnie wymagany próg.
Automatyzacja testów a11y
eslint-plugin-jsx-a11y (React)
Gdy zaczniesz pisać w React w świecie Podróży w Kosmos, linter ESLint z wtyczką jsx-a11y wyłapie błędy dostępności już podczas pisania kodu:
1{
2 "plugins": ["jsx-a11y"],
3 "rules": {
4 "jsx-a11y/alt-text": "error",
5 "jsx-a11y/anchor-has-content": "error",
6 "jsx-a11y/label-has-associated-control": "error",
7 "jsx-a11y/no-noninteractive-element-interactions": "warn"
8 }
9}Każda reguła to jedno sprawdzenie - alt-text zgłosi obraz bez tekstu alternatywnego, a label-has-associated-control pole bez etykiety. Poziom "error" traktuje problem jak błąd, a "warn" tylko ostrzega.
axe-core w testach
Silnik axe-core możesz też uruchamiać w testach automatycznych, żeby każda zmiana w kodzie była sprawdzana bez Twojego udziału:
1<!-- Przykład wyniku testu axe-core: -->
2<!--
3 Rule: color-contrast
4 Description: Elements must have sufficient color contrast
5 Help: Fix any of the following:
6 Element has insufficient color contrast of 2.5:1
7 Expected minimum: 4.5:1
8 Target: .subtitle
9-->Reguła color-contrast znalazła tekst o kontraście 2.5:1 przy wymaganym 4.5:1 i wskazała selektor .subtitle - wiesz dokładnie, co poprawić.
Checklist dostępności - kompletna lista
Na koniec lista kontrolna całego modułu, ułożona od fundamentów - semantyki i języka strony - po zaawansowane atrybuty ARIA:
1<!-- Struktura HTML -->
2<!-- [ ] Poprawna hierarchia nagłówków (h1-h6) -->
3<!-- [ ] Semantyczne znaczniki (header, nav, main, footer) -->
4<!-- [ ] Język strony (lang="pl") -->
5
6<!-- Obrazy -->
7<!-- [ ] Alt text dla obrazów informacyjnych -->
8<!-- [ ] Pusty alt="" dla dekoracyjnych -->
9
10<!-- Nawigacja -->
11<!-- [ ] Skip link -->
12<!-- [ ] Widoczny focus -->
13<!-- [ ] Logiczna kolejność Tab -->
14
15<!-- Formularze -->
16<!-- [ ] Label dla każdego pola -->
17<!-- [ ] Komunikaty o błędach -->
18<!-- [ ] aria-required dla wymaganych pól -->
19
20<!-- Kolor i kontrast -->
21<!-- [ ] Kontrast minimum 4.5:1 -->
22<!-- [ ] Informacja nie tylko przez kolor -->
23
24<!-- Multimedia -->
25<!-- [ ] Napisy do wideo -->
26<!-- [ ] Transkrypcje do audio -->
27
28<!-- ARIA -->
29<!-- [ ] aria-label dla przycisków-ikon -->
30<!-- [ ] aria-live dla dynamicznych treści -->
31<!-- [ ] aria-expanded dla rozwijanek -->Idź od góry: bez semantyki i lang nawet najlepsze ARIA nie pomoże. Przy przyciskach-ikonach sprawdź też, czy sama ikona ma aria-hidden="true", żeby czytnik odczytał tylko nazwę z aria-label.
Testowanie dostępności to jak weryfikacja, czy każdy korytarz w piramidzie prowadzi dokąd powinien - systematyczne sprawdzanie każdego elementu, aby upewnić się, że każdy odwiedzający dotrze do celu. W projekcie końcowym tego modułu przejdziesz tę listę na własnej stronie.
Praktyka
Przejdź interaktywną checklistę z edytora poniżej punkt po punkcie:
Kod do tej lekcji: index.html
1<!DOCTYPE html>
2<html lang="pl">
3<head>
4 <meta charset="UTF-8">
5 <meta name="viewport" content="width=device-width, initial-scale=1.0">
6 <title>Testowanie dostepnosci - checklist</title>
7 <link rel="stylesheet" href="style.css">
8</head>
9<body>
10 <h1>Checklist testowania dostepnosci</h1>
11
12 <section>
13 <h2>1. Test klawiatury</h2>
14 <p>Nawiguj po tej stronie uzywajac <kbd>Tab</kbd> i sprawdz:</p>
15 <ul class="checklist">
16 <li><label><input type="checkbox"> Kazdy element interaktywny jest osiagalny Tabem</label></li>
17 <li><label><input type="checkbox"> Focus jest widoczny na kazdym elemencie</label></li>
18 <li><label><input type="checkbox"> Kolejnosc focusu jest logiczna</label></li>
19 <li><label><input type="checkbox"> Przyciski reaguja na Enter i Spacje</label></li>
20 </ul>
21 </section>
22
23 <section>
24 <h2>2. Test struktury HTML</h2>
25 <ul class="checklist">
26 <li><label><input type="checkbox"> Strona ma poprawna hierarchie h1-h6</label></li>
27 <li><label><input type="checkbox"> Uzyto semantycznych znacznikow</label></li>
28 <li><label><input type="checkbox"> Jezyk strony jest okreslony (lang="pl")</label></li>
29 <li><label><input type="checkbox"> Wszystkie ID sa unikalne</label></li>
30 </ul>
31 </section>
32
33 <section>
34 <h2>3. Test obrazow</h2>
35 <div class="test-area">
36 <figure>
37 <img src="https://placehold.co/300x200/d4af37/1a1a2e?text=Sfinks"
38 alt="Wielki Sfinks w Gizie strzegacy piramid">
39 <figcaption>Wielki Sfinks - obraz z tekstem alt</figcaption>
40 </figure>
41 <img src="https://placehold.co/400x3/d4af37/d4af37" alt="">
42 <p><em>Dekoracyjna linia powyzej ma alt=""</em></p>
43 </div>
44 <ul class="checklist">
45 <li><label><input type="checkbox"> Informacyjne obrazy maja opisowy alt</label></li>
46 <li><label><input type="checkbox"> Dekoracyjne obrazy maja alt=""</label></li>
47 </ul>
48 </section>
49
50 <section>
51 <h2>4. Test formularzy</h2>
52 <form class="test-form">
53 <div class="form-group">
54 <label for="test-name">Imie:</label>
55 <input type="text" id="test-name" aria-required="true">
56 </div>
57 <div class="form-group">
58 <label for="test-email">Email:</label>
59 <input type="email" id="test-email"
60 aria-describedby="test-email-hint">
61 <p id="test-email-hint" class="hint">Format: jan@example.com</p>
62 </div>
63 <button type="button" onclick="validateForm()">Sprawdz formularz</button>
64 <div id="form-result" aria-live="polite"></div>
65 </form>
66 <ul class="checklist">
67 <li><label><input type="checkbox"> Kazde pole ma label</label></li>
68 <li><label><input type="checkbox"> Wymagane pola oznaczone aria-required</label></li>
69 <li><label><input type="checkbox"> Bledy opisane aria-describedby</label></li>
70 </ul>
71 </section>
72
73 <section>
74 <h2>5. Test kontrastu</h2>
75 <div class="contrast-test">
76 <p class="pass-aa">Ten tekst spelnia WCAG AA (kontrast > 4.5:1)</p>
77 <p class="fail">Ten tekst NIE spelnia wymagan (kontrast < 3:1)</p>
78 </div>
79 <ul class="checklist">
80 <li><label><input type="checkbox"> Kontrast tekstu minimum 4.5:1</label></li>
81 <li><label><input type="checkbox"> Informacja nie tylko przez kolor</label></li>
82 </ul>
83 </section>
84
85 <script>
86 function validateForm() {
87 const name = document.getElementById('test-name').value;
88 const result = document.getElementById('form-result');
89 if (!name) {
90 result.innerHTML = '<p class="error" role="alert">Wypelnij pole Imie!</p>';
91 } else {
92 result.innerHTML = '<p class="success">Formularz poprawny!</p>';
93 }
94 }
95 </script>
96</body>
97</html>Pamiętaj: automat to pierwszy strażnik u wejścia do piramidy, ale dopiero przejście korytarzy z klawiaturą i czytnikiem pokaże, czy każdy dotrze do komnaty.
Widzisz błąd w tej lekcji?
Sprawdź się
Odpowiedz na pytania z tej lekcji. Wybierz odpowiedź, a od razu zobaczysz, czy jest poprawna.
1. Gdzie można uruchomić narzędzie Lighthouse do testowania dostępności?
2. Co robi media query @media (prefers-reduced-motion: reduce)?
Zadania praktyczne w grze
- Układanie w pionie
Ułóż etapy testowania dostępności od automatycznego do ręcznego:
- Układanie w pionie
Ułóż poprawną strukturę elementu figure z opisem:
- Układanie w pionie
Ułóż poprawne media query do wyłączenia animacji:
- Edytor kodu
Przetestuj formularz - kliknij Wyślij bez wypełniania pól. Sprawdź jak aria-invalid, aria-describedby i role="alert" informują o błędach.
- Klikanie w kolejności
Ułóż poprawny komunikat błędu z atrybutami ARIA:
- Układanie w pionie
Ułóż elementy checklisty a11y od najważniejszych (fundamenty) do zaawansowanych:
- Układanie w poziomie
Ułóż poprawną składnię linku aktualnej strony z aria-current:
- Klikanie w kolejności
Ułóż poprawny przycisk z ikoną i aria-label:
- Układanie w pionie
Ułóż landmark roles w typowej kolejności na stronie (od góry do dołu):
- Edytor kodu
Znajdź i napraw wszystkie 8 błędów dostępności na tej stronie. Każdy błąd jest oznaczony komentarzem.