Lekcja 7.4: Dostępność tabel (scope, headers)
Dlaczego dostępność tabel jest ważna?
Tabele, zwłaszcza te bardziej złożone, mogą być trudne do zrozumienia dla osób korzystających z technologii wspomagających, takich jak czytniki ekranu. Bez odpowiednich wskazówek semantycznych, czytnik może odczytywać komórki wiersz po wierszu, bez jasnego powiązania danych z ich nagłówkami, co czyni tabelę bezużyteczną.
HTML dostarcza mechanizmów, które pozwalają jawnie określić relacje między komórkami nagłówkowymi (<th>) a komórkami danych (<td>), znacząco poprawiając dostępność tabel. Są to głównie atrybuty scope i headers.
Atrybut `scope`
Atrybut scope dodaje się do znacznika <th>, aby wskazać, jakiego zakresu komórek dotyczy dany nagłówek. Jest to prostszy i często wystarczający sposób na poprawę dostępności w standardowych tabelach.
Możliwe wartości atrybutu scope:
col: Nagłówek dotyczy kolumny, w której się znajduje. Używany dla nagłówków na górze kolumn.row: Nagłówek dotyczy wiersza, w którym się znajduje. Używany dla nagłówków na początku wierszy.colgroup: Nagłówek dotyczy grupy kolumn (omówimy<colgroup>później).rowgroup: Nagłówek dotyczy grupy wierszy (np. wierszy w obrębie<tbody>,<thead>lub<tfoot>).
Przykład użycia `scope`:
<table class="basic-table">
<thead>
<tr>
<th></th> <!-- Pusta komórka w rogu -->
<th scope="col">Poniedziałek</th>
<th scope="col">Wtorek</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">8:00</th>
<td>Matematyka</td>
<td>J. Polski</td>
</tr>
<tr>
<th scope="row">9:00</th>
<td>Fizyka</td>
<td>Historia</td>
</tr>
</tbody>
</table>
| Poniedziałek | Wtorek | |
|---|---|---|
| 8:00 | Matematyka | J. Polski |
| 9:00 | Fizyka | Historia |
W tym przykładzie:
- Nagłówki "Poniedziałek" i "Wtorek" mają
scope="col", wskazując, że opisują dane w swoich kolumnach. - Nagłówki "8:00" i "9:00" mają
scope="row", wskazując, że opisują dane w swoich wierszach.
Dzięki temu czytnik ekranu, napotykając np. komórkę "Matematyka", może poinformować użytkownika, że dotyczy ona godziny "8:00" w "Poniedziałek".
Atrybuty `id` i `headers`
W bardziej złożonych tabelach, zwłaszcza tych z połączonymi komórkami (colspan/rowspan) lub wielopoziomowymi nagłówkami, sam atrybut scope może nie wystarczyć do jednoznacznego określenia relacji. W takich przypadkach używa się kombinacji atrybutów id (w komórkach nagłówkowych <th>) i headers (w komórkach danych <td>).
- Nadanie
idnagłówkom: Każdej komórce nagłówkowej<th>, która ma być powiązana z danymi, nadajemy unikalny atrybutid. - Użycie
headersw komórkach danych: W każdej komórce danych<td>(a czasem też w<th>niższego poziomu) dodajemy atrybutheaders. Jego wartością jest lista identyfikatorów (id) odpowiednich komórek nagłówkowych, oddzielonych spacjami. Lista ta wskazuje, które nagłówki opisują daną komórkę.
Przykład użycia `id` i `headers`:
Rozważmy tabelę z dwupoziomowymi nagłówkami kolumn.
<table class="basic-table">
<thead>
<tr>
<th rowspan="2" id="dzien">Dzień</th>
<th colspan="2" id="dane">Dane pogodowe</th>
</tr>
<tr>
<th id="temp" headers="dane">Temperatura (°C)</th>
<th id="opady" headers="dane">Opady (mm)</th>
</tr>
</thead>
<tbody>
<tr>
<td headers="dzien">Poniedziałek</td>
<td headers="dane temp dzien">15</td>
<td headers="dane opady dzien">2</td>
</tr>
<tr>
<td headers="dzien">Wtorek</td>
<td headers="dane temp dzien">17</td>
<td headers="dane opady dzien">0</td>
</tr>
</tbody>
</table>
| Dzień | Dane pogodowe | |
|---|---|---|
| Temperatura (°C) | Opady (mm) | |
| Poniedziałek | 15 | 2 |
| Wtorek | 17 | 0 |
W tym przykładzie:
- Nagłówki mają unikalne
id("dzien", "dane", "temp", "opady"). - Nagłówki "Temperatura" i "Opady" same wskazują na swój nadrzędny nagłówek "Dane pogodowe" za pomocą
headers="dane". - Komórki danych (np. "15") w atrybucie
headerswymieniają wszystkieidnagłówków, które ich dotyczą ("dane temp dzien").
Dzięki temu czytnik ekranu, napotykając komórkę "15", może precyzyjnie poinformować: "Dzień: Poniedziałek, Dane pogodowe: Temperatura (°C): 15".
Kiedy używać `scope`, a kiedy `headers`?
scope: Jest preferowany dla prostszych tabel, gdzie każdy nagłówek jednoznacznie opisuje tylko jedną kolumnę lub jeden wiersz. Jest łatwiejszy w implementacji.headers+id: Jest konieczny w bardziej złożonych tabelach, zwłaszcza tych z połączonymi komórkami (colspan/rowspan) lub wielopoziomowymi nagłówkami, gdzie prostescope="col"lubscope="row"nie wystarcza do jednoznacznego powiązania danych z nagłówkami.
Zawsze staraj się tworzyć możliwie najprostszą strukturę tabeli, która poprawnie prezentuje dane. Jeśli tabela staje się bardzo skomplikowana, rozważ jej podział na kilka prostszych tabel.
Zadanie praktyczne (z rozwiązaniem)
Zadanie: Weź tabelę z planem lekcji z poprzedniego zadania (z rowspan) i dodaj do niej atrybuty scope do wszystkich komórek <th>, aby poprawić jej dostępność.
Rozwiązanie:
<!DOCTYPE html>
<html lang="pl">
<head>
<meta charset="UTF-8">
<title>Plan Lekcji - Dostępność</title>
<style>
table, th, td {
border: 1px solid #ccc;
border-collapse: collapse;
padding: 8px;
text-align: center;
}
thead { background-color: #f2f2f2; }
</style>
</head>
<body>
<h1>Plan Lekcji</h1>
<table>
<thead>
<tr>
<th scope="col">Godzina</th>
<th scope="col">Poniedziałek</th>
<th scope="col">Wtorek</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">8:00 - 8:45</th>
<td rowspan="2">Matematyka</td>
<td>Język Polski</td>
</tr>
<tr>
<th scope="row">9:00 - 9:45</th>
<td>Historia</td>
</tr>
<tr>
<td colspan="3">Przerwa</td>
</tr>
</tbody>
</table>
</body>
</html>
(Uwaga: W tym przypadku dodanie scope do nagłówków kolumn i wierszy znacząco poprawia dostępność. Dla komórki "Matematyka" z rowspan, czytnik ekranu powinien być w stanie powiązać ją z nagłówkiem kolumny "Poniedziałek" oraz z nagłówkami wierszy "8:00" i "9:00". W bardzo skomplikowanych przypadkach z rowspan można by rozważyć użycie headers.)
Dodatkowe zadania do samodzielnego wykonania:
- Stwórz tabelę z wielopoziomowymi nagłówkami (np. rok podzielony na kwartały) i użyj atrybutów
idiheaders, aby poprawnie powiązać dane z nagłówkami. - Przetestuj stworzone tabele za pomocą narzędzi do sprawdzania dostępności (np. WAVE, Lighthouse w narzędziach deweloperskich Chrome) lub, jeśli masz możliwość, za pomocą czytnika ekranu (NVDA, VoiceOver).
- Znajdź w internecie przykład złożonej tabeli i spróbuj dodać do niej atrybuty
scopelubheaders/id, aby poprawić jej dostępność.
Najczęściej zadawane pytania
Jak poprawić dostępność tabel HTML?
Używaj poprawnie nagłówków <th>. W prostych tabelach dodaj atrybut scope="col" lub scope="row" do <th>. W złożonych tabelach użyj kombinacji unikalnych id w <th> i atrybutu headers w <td>, aby jawnie powiązać dane z nagłówkami.
Do czego służy atrybut scope?
Atrybut scope, używany w <th>, wskazuje, czy nagłówek dotyczy kolumny (scope="col"), wiersza (scope="row"), grupy kolumn (scope="colgroup") czy grupy wierszy (scope="rowgroup"). Pomaga to technologiom wspomagającym zrozumieć strukturę tabeli.
Jak działają atrybuty id i headers?
Nadajesz unikalne id komórkom nagłówkowym (<th>). Następnie w komórkach danych (<td>) używasz atrybutu headers, podając listę id odpowiednich nagłówków oddzielonych spacjami. To jawnie wskazuje, które nagłówki opisują daną komórkę.
Kiedy używać scope, a kiedy headers?
Używaj scope dla prostych tabel, gdzie relacje nagłówek-dane są jednoznaczne. Używaj headers + id dla złożonych tabel, zwłaszcza tych z połączonymi komórkami (colspan/rowspan) lub wielopoziomowymi nagłówkami, gdzie scope może być niewystarczający.
Czy złożone tabele są zawsze problemem dla dostępności?
Złożone tabele stanowią większe wyzwanie, ale przy poprawnym użyciu semantycznych znaczników (<thead>, <tbody>, <tfoot>, <th>) oraz atrybutów scope lub headers/id, można je uczynić dostępnymi. Warto jednak rozważyć uproszczenie struktury, jeśli to możliwe.