Kurs HTML i CSS · Moduł 10: Dostępność (a11y)

Semantyczny HTML a dostępność

6 min czytania
W tej lekcji7

Wyobraź sobie niewidomego pielgrzyma, który wchodzi do świątyni, w której żadna komnata nie ma napisu nad wejściem. Słyszy echo kroków, ale nie wie, czy stoi w sali modlitw, czy w magazynie. Tak samo czuje się użytkownik czytnika ekranowego na stronie zbudowanej z samych <div>. W Starożytnym Egipcie hieroglify miały ściśle określone znaczenie - każdy symbol pełnił konkretną funkcję. Podobnie jest z semantycznym HTML: każdy znacznik niesie ze sobą informację o roli i znaczeniu treści, co jest kluczowe dla technologii wspomagających.

Dlaczego semantyka jest tak ważna?

Czytniki ekranowe (screen readers) nie "widzą" strony - odczytują jej strukturę HTML. Gdy używasz <div> do wszystkiego, czytnik nie wie, co jest nawigacją, co nagłówkiem, a co treścią główną. Porównaj dwie wersje tego samego fragmentu strony muzeum - najpierw "zupę z divów", potem wersję semantyczną:

1<!-- ŹLE - "zupa z divów" -->
2<div class="header">
3    <div class="nav">
4        <div class="nav-item">Strona główna</div>
5        <div class="nav-item">O nas</div>
6    </div>
7</div>
8<div class="content">
9    <div class="title">Witaj w muzeum</div>
10    <div class="text">Opis wystawy...</div>
11</div>
12
13<!-- DOBRZE - semantyczny HTML -->
14<header>
15    <nav aria-label="Nawigacja główna">
16        <ul>
17            <li><a href="/">Strona główna</a></li>
18            <li><a href="/about">O nas</a></li>
19        </ul>
20    </nav>
21</header>
22<main>
23    <h1>Witaj w muzeum</h1>
24    <p>Opis wystawy...</p>
25</main>

Obie wersje mogą wyglądać identycznie, bo CSS potrafi upodobnić <div> do czegokolwiek. Różnica jest niewidoczna dla oka, ale ogromna dla czytnika: w drugiej wersji ogłosi on nawigację z listą dwóch linków, a użytkownik jednym skrótem klawiszowym przeskoczy do treści głównej. Treść się nie zmieniła - zmieniły się tylko znaczniki, a zwykłe napisy w menu stały się prawdziwymi linkami.

Kluczowe znaczniki semantyczne

Elementy sekcjonujące

Oto siedem znaczników, z których zbudujesz szkielet niemal każdej strony. Traktuj je jak napisy nad wejściami do komnat - każdy mówi, co znajduje się w środku:

1<header>  <!-- Nagłówek strony lub sekcji -->
2<nav>     <!-- Nawigacja -->
3<main>    <!-- Główna treść strony (tylko jeden na stronę!) -->
4<article> <!-- Samodzielna treść (post, artykuł) -->
5<section> <!-- Tematyczna grupa treści -->
6<aside>   <!-- Treść poboczna (sidebar) -->
7<footer>  <!-- Stopka strony lub sekcji -->

Zwróć uwagę na komentarz przy <main>: strona ma dokładnie jeden widoczny element <main> (specyfikacja HTML dopuszcza kolejne tylko wtedy, gdy są ukryte atrybutem hidden). Inaczej jest z <header> i <footer> - mogą pojawić się wielokrotnie, na przykład w każdym <article> z osobna.

Hierarchia nagłówków

Nagłówki tworzą strukturę dokumentu. Czytniki ekranowe pozwalają nawigować po nagłówkach - w czytniku NVDA klawisz H przenosi do następnego - więc wielu użytkowników najpierw "przegląda" stronę samymi nagłówkami, jak pielgrzym czytający tylko tablice nad komnatami. Dlatego ich hierarchia musi być poprawna:

1<!-- ŹLE - pominięty poziom h2 -->
2<h1>Muzeum Egipskie</h1>
3<h3>Wystawy stałe</h3>     <!-- Powinno być h2! -->
4<h4>Skarby faraonów</h4>   <!-- Powinno być h3! -->
5
6<!-- DOBRZE - poprawna hierarchia -->
7<h1>Muzeum Egipskie</h1>
8<h2>Wystawy stałe</h2>
9<h3>Skarby faraonów</h3>
10<h3>Mumie królewskie</h3>
11<h2>Wystawy czasowe</h2>
12<h3>Złoto Tutanchamona</h3>

Poziom nagłówka oznacza miejsce w hierarchii, a nie wielkość liter. Jeśli <h2> wydaje Ci się za duży, zmniejsz go w CSS, ale nie przeskakuj do <h3> - czytnik uzna wtedy, że w dokumencie brakuje jednego poziomu. Kolejność jest zawsze ta sama: od <h1> (tytuł strony), przez <h2> i <h3>, aż do <h6>.

Listy

Listy też niosą znaczenie. Gdy linki nawigacji siedzą w <ul>, czytnik zapowie liczbę elementów, zanim użytkownik zacznie ich słuchać. Z kolei lista definicji <dl> łączy termin (<dt>) z objaśnieniem (<dd>), jak słownik skryby:

1<!-- Nawigacja jako lista - czytnik powie "lista, 4 elementy" -->
2<nav>
3    <ul>
4        <li><a href="/">Strona główna</a></li>
5        <li><a href="/exhibitions">Wystawy</a></li>
6        <li><a href="/tickets">Bilety</a></li>
7        <li><a href="/contact">Kontakt</a></li>
8    </ul>
9</nav>
10
11<!-- Lista definicji -->
12<dl>
13    <dt>Skarabeusz</dt>
14    <dd>Święty żuk symbolizujący odrodzenie</dd>
15    <dt>Ankh</dt>
16    <dd>Symbol życia wiecznego</dd>
17</dl>

Punkty przy linkach usuniesz jedną regułą w CSS - wygląd to sprawa arkusza stylów, a znaczenie to sprawa HTML.

Landmark roles

Semantyczne znaczniki HTML automatycznie tworzą tzw. landmarks (punkty orientacyjne), po których użytkownicy czytników ekranowych mogą szybko nawigować:

Znacznik HTMLLandmark RoleOpis
<header>bannerNagłówek strony
<nav>navigationNawigacja
<main>mainGłówna treść
<aside>complementaryTreść uzupełniająca
<footer>contentinfoStopka
<section>region*Sekcja tematyczna
<form>form*Formularz

*Wymaga atrybutu aria-label lub aria-labelledby.

Tabela pokazuje też typową kolejność landmarków od góry strony: banner, navigation, main, complementary i contentinfo. Jest jeden niuans: <header> i <footer> dostają role banner i contentinfo tylko wtedy, gdy nie są zagnieżdżone w <article>, <aside>, <main>, <nav> ani <section>. Te role są wbudowane, więc nie dopisuj role="navigation" do <nav> - to powtórzenie tej samej informacji.

Praktyczny przykład

Połączmy wszystko w jedną stronę muzeum. Przeczytaj kod od góry do dołu i spróbuj wskazać każdy landmark z tabeli powyżej:

1<!DOCTYPE html>
2<html lang="pl">
3<head>
4    <meta charset="UTF-8">
5    <title>Muzeum Starożytnego Egiptu</title>
6</head>
7<body>
8    <header>
9        <h1>Muzeum Starożytnego Egiptu</h1>
10        <nav aria-label="Nawigacja główna">
11            <ul>
12                <li><a href="/">Strona główna</a></li>
13                <li><a href="/exhibitions">Wystawy</a></li>
14            </ul>
15        </nav>
16    </header>
17
18    <main>
19        <article>
20            <h2>Wystawa: Skarby Tutanchamona</h2>
21            <p>Odkryj niesamowite artefakty...</p>
22            <figure>
23                <img src="mask.jpg" alt="Złota maska pośmiertna Tutanchamona">
24                <figcaption>Maska pośmiertna Tutanchamona, ok. 1323 p.n.e.</figcaption>
25            </figure>
26        </article>
27    </main>
28
29    <aside aria-label="Informacje dodatkowe">
30        <h2>Godziny otwarcia</h2>
31        <p>Pn-Pt: 9:00-17:00</p>
32    </aside>
33
34    <footer>
35        <p>Muzeum Starożytnego Egiptu 2024</p>
36    </footer>
37</body>
38</html>

Nie ma tu ani jednego <div>, a niczego nie brakuje. <aside> dostał aria-label, więc czytnik przedstawi go jako "Informacje dodatkowe", a <figure> z <figcaption> wiąże zdjęcie maski z jego podpisem.

Typowe błędy semantyczne

Na koniec trzy pułapki, w które wpada prawie każdy początkujący. Każda para pokazuje wersję błędną i poprawną:

1<!-- ŹLE: div zamiast button -->
2<div onclick="submit()">Wyślij</div>
3
4<!-- DOBRZE: natywny button -->
5<button onclick="submit()">Wyślij</button>
6
7<!-- ŹLE: span jako nagłówek -->
8<span class="big-text">Ważny tytuł</span>
9
10<!-- DOBRZE: właściwy nagłówek -->
11<h2>Ważny tytuł</h2>
12
13<!-- ŹLE: br do tworzenia odstępów -->
14<br><br><br>
15
16<!-- DOBRZE: CSS margin/padding -->
17<p style="margin-top: 2rem;">Tekst z odstępem</p>

<div> z onclick nie dostanie focusu z klawiatury i nie zareaguje na Enter ani Spację, a natywny <button> robi to wszystko sam. <span> udający nagłówek nie pojawi się na liście nagłówków czytnika, a seria <br> to dla czytnika puste linie, nie odstęp. Zauważ, że żadna poprawna wersja nie potrzebuje ani jednego atrybutu ARIA. Moja rada: zanim sięgniesz po <div>, zapytaj, czy HTML nie ma już elementu o tym znaczeniu - najczęściej ma i to on jest najlepszym wyborem.

Walidacja semantyki

Możesz sprawdzić semantykę swojej strony za pomocą:

  • W3C Validator - sprawdza poprawność HTML
  • WAVE - analizuje dostępność strony
  • Lighthouse - audyt dostępności w Chrome DevTools

Dokładniej poznasz je w lekcji o testowaniu dostępności, a w następnych lekcjach ten semantyczny szkielet stanie się podstawą nawigacji klawiaturowej.

Semantyczny HTML to fundament dostępności - tak jak solidne fundamenty piramidy zapewniają jej trwałość na tysiąclecia, tak poprawna semantyka zapewnia, że strona będzie dostępna dla wszystkich użytkowników. Każdy element HTML powinien odpowiadać swojej roli: nagłówek powinien być nagłówkiem, nawigacja nawigacją, a przycisk przyciskiem.

Praktyka

W edytorze poniżej znajdziesz semantyczną stronę muzeum. Zamień jeden ze znaczników na <div> i zastanów się, jaką informację stracił właśnie czytnik ekranowy:

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>Muzeum Starorzytnego Egiptu - Semantyczny HTML</title>
7    <link rel="stylesheet" href="style.css">
8</head>
9<body>
10    <header>
11        <h1>Muzeum Starorzytnego Egiptu</h1>
12        <nav aria-label="Nawigacja glowna">
13            <ul>
14                <li><a href="#exhibitions">Wystawy</a></li>
15                <li><a href="#artifacts">Artefakty</a></li>
16                <li><a href="#visit">Odwiedz nas</a></li>
17            </ul>
18        </nav>
19    </header>
20
21    <main>
22        <section id="exhibitions" aria-labelledby="ex-title">
23            <h2 id="ex-title">Aktualne wystawy</h2>
24
25            <article>
26                <h3>Skarby Tutanchamona</h3>
27                <p>Odkryj niezwykle artefakty z grobowca mlodego faraona,
28                   odkrytego przez Howarda Cartera w 1922 roku.</p>
29                <figure>
30                    <img src="https://placehold.co/400x250/d4af37/1a1a2e?text=Maska+Tutanchamona"
31                         alt="Zlota maska posmiertna faraona Tutanchamona">
32                    <figcaption>Maska posmiertna Tutanchamona, ok. 1323 p.n.e.</figcaption>
33                </figure>
34            </article>
35
36            <article>
37                <h3>Mumie Krolewskie</h3>
38                <p>Poznaj tajemnice mumifikacji w Starorzytnym Egipcie.</p>
39            </article>
40        </section>
41
42        <section id="artifacts" aria-labelledby="art-title">
43            <h2 id="art-title">Kolekcja artefaktow</h2>
44            <dl>
45                <dt>Skarabeusz</dt>
46                <dd>Swiety zuk symbolizujacy odrodzenie i stworzenie</dd>
47                <dt>Ankh</dt>
48                <dd>Symbol zycia wiecznego, nosznoy przez faraonow</dd>
49                <dt>Oko Horusa</dt>
50                <dd>Symbol ochrony, zdrowia i krolewskiej wladzy</dd>
51            </dl>
52        </section>
53    </main>
54
55    <aside aria-label="Informacje dodatkowe">
56        <h2>Godziny otwarcia</h2>
57        <p>Pn-Pt: 9:00-17:00</p>
58        <p>Sb-Nd: 10:00-18:00</p>
59    </aside>
60
61    <footer>
62        <p>Muzeum Starorzytnego Egiptu &copy; 2024</p>
63        <nav aria-label="Linki stopki">
64            <ul>
65                <li><a href="/privacy">Polityka prywatnosci</a></li>
66                <li><a href="/accessibility">Deklaracja dostepnosci</a></li>
67            </ul>
68        </nav>
69    </footer>
70</body>
71</html>

Pamiętaj: znacznik semantyczny to napis nad wejściem do komnaty - dzięki niemu każdy odwiedzający wie, dokąd prowadzi korytarz, nawet jeśli nie widzi ścian.

Widzisz błąd w tej lekcji?

Sprawdź się

Odpowiedz na pytania z tej lekcji. Wybierz odpowiedź, a od razu zobaczysz, czy jest poprawna.

  1. 1. Ile elementów <main> może znajdować się na jednej stronie HTML?

  2. 2. Dlaczego poprawna hierarchia nagłówków (h1-h6) jest ważna dla dostępności?

Zadania praktyczne w grze

  • Edytor kodu

    Zamień divy na semantyczne znaczniki HTML: header, nav (z aria-label), main, article, aside i footer.

  • Układanie w pionie

    Ułóż nagłówki HTML od najważniejszego do najmniej ważnego:

Przydatne artykuły