noxee.io - Digital Accessibility

Blog

Digital Accessibility Blog – tips, analyses, examples

Dostępność cyfrowa w praktyce – wiedza, narzędzia i inspiracje

Aria (atrybuty opisujące)

2025-06-09

ARIA (Accessible Rich Internet Applications) to zestaw atrybutów, które wspierają osoby korzystające z czytników ekranu. Na wielu stronach internetowych elementy takie jak przyciski, formularze czy rozwijane panele są w pełni zrozumiałe wizualnie, ale mogą być nieczytelne dla kogoś, kto nie widzi ekranu lub nie posługuje się myszką. I właśnie tu z pomocą przychodzi ARIA.

To narzędzia, które pozwalają opisać, co dokładnie dzieje się na stronie. Możemy przekazać użytkownikowi: „to jest przycisk”, „tu trwa ładowanie”, „w tym miejscu otworzył się dialog”. To trochę tak, jakbyśmy opowiadali, co się dzieje na scenie komuś, kto jej nie widzi — spokojnie, jasno i bez zbędnych komplikacji.

Zacznijmy od atrybutów opisujących ARIA - to te, które mówią, jak coś się nazywa lub co znaczy.

aria-label

Atrybut aria-label pozwala dodać nazwę (etykietę) do elementu, który sam w sobie nie ma widocznego tekstu. Dzięki temu osoby korzystające z czytników ekranu wiedzą, co dany element robi — nawet jeśli nie ma tam żadnego napisu.

To bardzo przydatne w przypadku ikon, przycisków tylko z grafiką, interaktywnych elementów grupujących (div), a także w formularzach, gdzie np. nie chcemy używać klasycznego - label. Czytnik ekranu przeczyta zawartość z aria-label tak, jakby to był tekst widoczny dla użytkownika.

<button aria-label="Zamknij okno"> <img src="close.svg" alt=""> </button>

To co widzicie powyżej to bardzo popularne wykorzystanie aria. Dla czytnika sytuacja jest zrozumiała - “Zamknij okno, przycisk”, bo aria-label nadaje nazwę całemu elementowi – niezależnie od tego, co zawiera w środku. Czytnik nie analizuje wtedy zawartości, czy tam jest obrazek, SVG, div, nic – po prostu czyta etykietę z aria-label.

I teraz powinna się zacząć seria pytań. Dlaczego wykorzystaliśmy aria-label jako parametr button, a nie wpisałem alt przy obrazku. Mój kod mógłby wyglądać tak: <button><img src="close.svg" alt="Zamknij okno"></button>

Czytnik przeczyta dokładnie tą samą informację - “Zamknij okno, przycisk”. Jaka zatem jest różnica?

Obie wersje są semantycznie poprawne – ale aria-label daje większą kontrolę i lepiej sprawdza się, gdy chcesz uniezależnić opis od grafiki. Aria wykorzystasz gdy grafika nie wnosi dodatkowej treści – jest tylko ikoną np. funkcji. Gdy tekst etykiety chcesz kontrolować technicznie, niezależnie od zawartości obrazka. Gdy zależy Ci na większej elastyczności (np. możesz później łatwo dodać aria-describedby, zmienić aria-label przez JavaScript itd.). I w końcu, gdy ta sama grafika może mieć różne znaczenie w zależności od kontekstu.

Zatem, dopisz alt do ikony będącej przyciskiem, gdy masz pewność, że alt w pełni opisuje działanie tego przycisku lub gdy zależy ci na prostym i lekkim kodzie, bez nadmiarowych atrybutów. Kluczem jest kontekst i przejrzystość dla użytkownika korzystającego z czytnika.

Niektórzy z was, od razu zapytają - jeśli więc alt i aria-label przekazały podobną treść, dlaczego nie stosować wszędzie aria-label i zapomnieć o alt - tak jak poniżej?

<button> <img src="close.svg" aria-label="Zamknij okno"> </button>

Bo aria-label nie powinno zastępować alt na obrazkach. To właśnie alt jest semantycznym i zgodnym z HTML sposobem opisania zawartości grafiki. Czytnik ekranu przeczyta ten tekst jako nazwę grafiki. To błąd. Czytnik nie przeczyta aria-label z obrazka, a w efekcie użytkownik nic nie usłyszy lub usłyszy tylko „grafika”.

Podsumowując, używaj alt dla obrazków, a aria-label dla elementów interaktywnych, takich jak button, div, a. Nie używaj aria-label zamiast alt na grafice, ale możesz użyć obu rzeczy razem, np. aria-label na przycisku i alt=”” na obrazku, by grafikę pominąć dla czytnika.

aria-labelledby

aria-labelledby to atrybut, który pozwala połączyć element z tekstem opisującym go – ale zamiast wpisywać ten opis bezpośrednio, wskazujemy inny element, którego treść ma zostać użyta jako etykieta. Dzięki temu użytkownik korzystający z czytnika ekranu usłyszy opis, który wynika z zawartości wskazanego elementu, a nie ze sztucznie nadanego tekstu.

To szczególnie przydatne na bardziej złożonych stronach, gdzie standardowe powiązanie np. label i input nie wystarcza. Przykładowo – gdy masz pole formularza, a jego opis składa się z kilku kawałków tekstu, nagłówka albo ikon z podpisami – możesz połączyć wszystko jednym aria-labelledby, wskazując identyfikatory tych elementów. Czytnik scali je i odczyta jako jeden opis.

Dzięki temu zachowujesz pełną kontrolę nad tym, jak użytkownik z technologiami asystującymi będzie odbierał treść, bez konieczności powielania tekstu czy osadzania go wewnątrz każdego komponentu.

<label id="email-label">Twój adres e-mail</label> <input type="email" aria-labelledby="email-label">

Użytkownik korzystający z czytnika ekranu, gdy skupi się na polu input, usłyszy: Twój adres e-mail, pole edycji lub podobny komunikat w zależności od używanego czytnika.

Dlaczego? Bo aria-labelledby="email-label" mówi czytnikowi, że etykietą tego pola jest tekst z elementu o id="email-label". Czytnik pobierze ten tekst – „Twój adres e-mail” – i przeczyta go jako nazwę tego pola formularza. Dodaje też domyślny opis, że to „pole edycji”, bo rozpoznaje type="email" jako edytowalne pole.

Dzięki temu użytkownik wie, czego dotyczy pole i co ma tam wpisać – a to właśnie cel dobrze użytej dostępności.

aria-describedby

Użycie aria-describedby pozwala rozbudować komunikat dla użytkownika – bez mieszania tego z główną etykietą. Daje to jasność: jedno mówi co to jest, drugie – co warto wiedzieć. Świetnie sprawdza się np. przy polach z podpowiedziami, błędami czy wymaganiami (np. „Hasło musi mieć co najmniej 8 znaków”).

<label for="password">Hasło</label> <input type="password" id="password" aria-describedby="password-help"> <p id="password-help">Hasło musi mieć co najmniej 8 znaków</p>

Użytkownik najpierw usłyszy etykietę pola – Hasło. To dzieje się dzięki powiązaniu label z polem input przez atrybut for. Następnie czytnik automatycznie odczyta dodatkową informację, która znajduje się w elemencie p wskazanym przez aria-describedby. W tym przypadku czytnik przeczyta Hasło musi mieć co najmniej 8 znaków.

Dla użytkownika oznacza to, że po wejściu w pole hasła od razu wie, czego się od niego oczekuje. Nie musi szukać opisu gdzieś obok, bo informacja jest odczytywana naturalnie, bez dodatkowych działań. To rozwiązanie jest wygodne, dostępne i zgodne z zasadami WCAG – poprawia zrozumiałość formularzy i zmniejsza ryzyko błędów przy ich wypełnianiu.

W kolejnym wpisie, zajmiemy się atrybutami dynamicznymi aria.