Anatomia dobrego przycisku - HTML
10 czerwca 2026·3 min czytania
Dostępność przycisków brzmi prosto: użyj odpowiedniego tagu, daj mu nazwę, zadbaj o kontrast i focus W praktyce masz kilka narzędzi do wyboru i każde z nich zachowuje się inaczej. Nie ma jednego złotego środka - jest za to kilka dobrze zdefiniowanych przypadków, które warto poznać.
W pierwszej części skupimy się na anatomii z punktu widzenia HTML.
Poniżej wspominam o klasiesr-only. O tym, czym ona jest, przeczytasz więcej na https://www.dostepny-frontend.pl/blog/sr-only
Skąd bierze się "dostępna nazwa"?
Przeglądarka oblicza tzw. accessible name - nazwę, którą usłyszy użytkownik czytnika ekranu lub wypowie do Voice Control. Dla przycisku przegląda kilka źródeł po kolei i zatrzymuje się na pierwszym, które coś zwraca:
aria-labelledbyaria-label- Treść tekstowa elementu (łącznie z dziećmi)
title
Kluczowa rzecz: aria-labelledby i aria-label nadpisują treść. Nie uzupełniają - zastępują.
Trzy scenariusze i co z nimi zrobić
1. Przycisk z widoczną etykietą
<button>Usuń komentarz</button>Treść jest dostępną nazwą. Nie trzeba nic dodawać. Dodawanie aria-label z identyczną wartością to redundancja - nieszkodliwa, ale bezcelowa. Jedna z naczelnych zasad, jakie usłyszysz na szkoleniu z dostępności cyfrowej brzmi: używaj aria-*tylko tam, gdzie jest to niezbędne.
2. Przycisk tylko z ikoną
<button>
<svg aria-hidden="true">...</svg>
</button>SVG jest ukryte przed czytnikiem przez aria-hidden- w 99% przypadków to element dekoracyjny. Przycisk nie ma żadnej dostępnej nazwy - to poważny błąd na poziomie A.
Rozwiązanie A: sr-only span
<button>
<svg aria-hidden="true">...</svg>
<span class="sr-only">Usuń komentarz</span>
</button>Rozwiązanie B: aria-label
<button aria-label="Usuń komentarz">
<svg aria-hidden="true">...</svg>
</button>Które wybrać?
Oba są poprawne. Preferuj jednak rozwiązanie A (sr-only span) tam, gdzie to możliwe, zgodnie z zasadą, aby używać aria-* dopiero w ostateczności.
3. Przycisk z widoczną etykietą, który potrzebuje kontekstu
To najciekawszy przypadek. Masz listę elementów i przycisk „Usuń" przy każdym z nich. Wizualnie kontekst jest jasny - ale dla czytnika ekranu lista samych „Usuń" to pułapka.
Rozwiązanie A: sr-only span
<button>
Usuń
<span class="sr-only">komentarz</span>
</button>Rozwiązanie B: aria-label
<button aria-label="Usuń komentarz">Usuń</button>Którą wybrać?
Tutaj również oba rozwiązania są poprawne, lecz preferuj rozwiązanie A oparte o sr-only.
Różnica jest mechaniczna: aria-label zastępuje całą dostępną nazwę, sr-only rozszerza treść tekstową elementu. Gdy widoczny tekst zmieni się podczas refaktoru i ktoś zapomni zaktualizować aria-label - masz naruszenie kryterium WCAG niewidoczne w code review. Z sr-only ten błąd jest strukturalnie niemożliwy: widoczny tekst zawsze wchodzi w skład nazwy.
Czy trzy powyższe przykłady to jedyne możliwości?
Nie, to przykłady podstawowe, najprostsze dla zobrazowania, jak niewiele potrzeba, aby z punktu widzenia HTML mieć poprawny przycisk. Nie opisałem tutaj wspomnianego wyżej aria-labelledby, nie wspominam przycisków tworzonych za pomocą div[role="button"], linkach, które wyglądają i działają jak przyciski i innych niestandardowych rzeczach. Tak tworzone "przyciski" też mogą być dostępne, ale o tym napiszę kiedy indziej.
Podsumowanie - rekomendowany pattern
Masz ikonę w przycisku? Na 99% chcesz ją ukryć za pomocą aria-hidden="true".
Etykieta - nie musi być widoczna, ale musi być. Użytkownicy posługujący się na przykład czytnikami ekranu potrzebują informacji, czym jest ten przycisk i do czego służy. sr-onlyjest prawidłowym rozwiązaniem.
A aria-label? To rozwiązanie też jest ok, jeśli sprawisz, że taki przycisk będzie dostępny - cel będzie osiągnięty.
Newsletter
Nowe artykuły o dostępności (jakości) prosto na Twoją skrzynkę. Bez spamu. Polityka prywatności.