Nieaktywne przyciski a dostępność
Zaktualizowano 14 października 2026 · 5 min czytania
Wyszarzone „Dodaj do koszyka”, dopóki nie wybierze się rozmiaru, przycisk „Zamawiam”, który pozostaje nieaktywny, dopóki nie wypełni się wszystkich pól – nieaktywne przyciski są w sklepach internetowych wszędzie. WCAG przewiduje dla nich konkretne zwolnienie, ale to nie znaczy, że zawsze są dobrym pomysłem. Ta strona omawia zasady, dwa sposoby wyłączenia przycisku i lepsze alternatywy. Należy do serii dostępne wzorce interfejsu.
Co mówi WCAG
- Zwolnienie z wymogu kontrastu. 1.4.3 Kontrast (minimum) wyłącza „tekst lub obrazy tekstu, które są częścią nieaktywnego komponentu interfejsu użytkownika”, a 1.4.11 Kontrast elementów nietekstowych także wyłącza nieaktywne komponenty. W3C definiuje nieaktywny komponent jako taki, który „jest widoczny, ale w danej chwili nie można go obsługiwać”, i jako przykład podaje nieaktywny przycisk wysyłania formularza. Dokument Understanding wyjaśnia, że zwolnienie istnieje, bo nie znaleziono jednego dobrego sposobu pokazywania nieaktywnych kontrolek.
- Nazwa, rola, stan. 4.1.2 Nazwa, rola, wartość: stan nieaktywny musi być zapisany w kodzie, a nie tylko pokazany szarym kolorem.
- Instrukcje. 3.3.2 Etykiety lub instrukcje: jeśli użytkownik musi coś zrobić, zanim przycisk zadziała, trzeba to powiedzieć.
- Błędy. 3.3.1 Identyfikacja błędu: nieaktywny przycisk wysyłania nie jest komunikatem o błędzie. Użytkownik nadal musi się dowiedzieć z tekstu, co jest nie tak.
Niski kontrast nieaktywnego przycisku nie jest więc niezgodnością z WCAG – ale nieaktywny przycisk, którego nikt nie rozumie, może nadal nie spełniać powyższych kryteriów i na pewno kosztuje sprzedaż.
disabled czy aria-disabled
Atrybut disabled |
aria-disabled="true" |
|
|---|---|---|
| Działa na | Natywnych kontrolkach formularzy: button, input, select, textarea, fieldset |
Każdym elemencie z rolą interaktywną |
| Można go aktywować | Nie, przeglądarka to blokuje | Tak – skrypt musi zignorować akcję |
| W kolejności tabulacji | Nie | Tak |
| Czytnik ekranu odczytuje „niedostępny”/„wyszarzony” | Tak | Tak |
Przewodnik APG o obsłudze klawiatury mówi, że „przeglądarki usuwają z kolejności tabulacji elementy HTML input z atrybutem disabled”. Tam, gdzie użytkownik musi odkryć nieaktywny element – APG wymienia pozycje menu, zakładki, opcje listy wyboru i elementy drzewa – stosuje aria-disabled="true", aby element nadal przyjmował fokus. Wzorzec przycisku w APG mówi też, że gdy akcja przycisku jest niedostępna, „przycisk ma aria-disabled ustawione na true”.
Praktyczna zasada: disabled, gdy nie ma znaczenia, że przycisk zostanie pominięty; aria-disabled, gdy użytkownik musi znaleźć przycisk i dowiedzieć się, dlaczego nie działa.
Przykład kodu
<!-- Wykrywalny: zostaje w kolejności tabulacji, powód jest odczytywany -->
<p id="size-hint">Wybierz rozmiar, aby dodać ten produkt do koszyka.</p>
<button type="button" id="add" aria-disabled="true" aria-describedby="size-hint">
Dodaj do koszyka
</button>
<script>
const add = document.getElementById('add');
add.addEventListener('click', (event) => {
if (add.getAttribute('aria-disabled') === 'true') {
event.preventDefault(); // zablokuj akcję samodzielnie
document.getElementById('size').focus();
return;
}
addToCart();
});
// Po wybraniu rozmiaru: add.setAttribute('aria-disabled', 'false');
</script>
<!-- Można pominąć: natywna nieaktywna kontrolka, do której użytkownik nie musi docierać -->
<button type="button" disabled>Poprzednia strona</button>
Proszę ostylować [aria-disabled="true"] tak, by wyglądał na niedostępny – przeglądarka nie zrobi tego sama.
Lepsze alternatywy
- Zostawić „Zamawiam” aktywne. Gdy zostanie naciśnięte przy brakujących danych, pokazać komunikaty o błędach tekstem i przenieść fokus na pierwszy błąd lub podsumowanie błędów. Zob. walidacja formularzy i komunikaty o błędach.
- Napisać, czego brakuje obok nieaktywnego przycisku, widocznym tekstem, a nie w podpowiedzi po najechaniu.
- Nie ukrywać niedostępnej opcji bez wyjaśnienia – wyprzedany rozmiar może zostać na liście z oznaczeniem „wyprzedane”.
Obsługa klawiaturą
| Klawisz | Przycisk z disabled |
Przycisk z aria-disabled |
|---|---|---|
| Tab | Pomija przycisk | Przenosi na niego fokus; czytnik ekranu mówi, że jest niedostępny, i odczytuje opis |
| Enter / Spacja | Nic | Nic się nie dzieje – albo skrypt przenosi fokus tam, gdzie czegoś brakuje |
Typowe błędy w sklepach internetowych
- „Dodaj do koszyka” nieaktywne do czasu wyboru wariantu, bez widocznej wskazówki. Użytkownik klawiatury nigdy nie dociera do przycisku i nie wie dlaczego.
- Przycisk „Zapłać” nieaktywny, dopóki wszystkie pola nie przejdą walidacji, podczas gdy pola nie pokazują żadnych komunikatów o błędach.
- Przycisk, który wygląda na nieaktywny, ale nim nie jest (tylko szary styl), albo nieaktywny w kodzie, a wyglądający na aktywny.
aria-disabled="true"bez zabezpieczenia w skrypcie, przez co przycisk nadal wysyła formularz.- Stan nieaktywny pokazany tylko mniejszą nieprzezroczystością, a powód w podpowiedzi
title. - Nieczytelnie jasny tekst nieaktywny przy ważnej informacji, np. „Brak w magazynie”. Tekst może być zwolniony z wymogu kontrastu, ale informacja powinna być też dostępna w czytelnym tekście.
Co wychwytuje kontrola automatyczna, a co wymaga testu ręcznego
| Automatycznie (reguła axe-core) | Co znajduje |
|---|---|
color-contrast |
Tekst o niskim kontraście; nieaktywne kontrolki są pomijane, bo WCAG je zwalnia |
button-name |
Przyciski bez nazwy, aktywne lub nie |
aria-valid-attr-value |
aria-disabled z nieprawidłową wartością, aria-describedby wskazujące nieistniejący identyfikator |
aria-allowed-attr |
Atrybuty ARIA niedozwolone dla roli elementu |
Wszystkie to karty z naszej biblioteki reguł. Test ręczny: proszę spróbować wypełnić formularz lub wybrać produkt wyłącznie klawiaturą, sprawdzić, czy każda nieaktywna kontrolka ma widoczny powód, i sprawdzić czytnikiem ekranu, czy stan i powód są odczytywane. Narzędzie do sprawdzania kontrastu pomaga dobrać styl nieaktywny, który pozostaje czytelny.
Proszę uruchomić darmową kontrolę jednej strony. To automatyczna kontrola, a nie pełny audyt.
Najczęstsze pytania
Czy nieaktywne przyciski muszą spełniać wymogi kontrastu WCAG?
Nie. Zarówno 1.4.3 Kontrast (minimum), jak i 1.4.11 Kontrast elementów nietekstowych zwalniają z wymogu nieaktywne komponenty interfejsu, które W3C definiuje jako widoczne, ale w danej chwili nieobsługiwalne. Przykładem podanym przez W3C jest nieaktywny przycisk wysyłania formularza.
Czym różni się disabled od aria-disabled?
Atrybut HTML disabled sprawia, że natywnej kontrolki nie da się użyć, i usuwa ją z kolejności tabulacji. aria-disabled="true" informuje tylko technologię wspomagającą, że kontrolka jest niedostępna; nadal przyjmuje fokus, a akcję trzeba zablokować we własnym skrypcie.
Czy blokowanie przycisku wysyłania do czasu poprawnego wypełnienia formularza to zły pomysł?
Często sprawia kłopoty: użytkownik nie może się dowiedzieć, czego brakuje, a użytkownik klawiatury nie dociera nawet do przycisku. Zwykle lepiej działa przycisk aktywny i jasne komunikaty o błędach po wysłaniu.
Jak wyjaśnić, dlaczego przycisk jest nieaktywny?
Umieścić powód w widocznym tekście obok przycisku, np. „Wybierz rozmiar, aby dodać do koszyka”, i powiązać go przez aria-describedby. Nie polegać na podpowiedzi po najechaniu myszą.
Czy kontrola automatyczna może przetestować nieaktywne przyciski?
Kontrole kontrastu pomijają nieaktywne kontrolki, tak jak WCAG. Reguły automatyczne sprawdzają, czy aria-disabled ma poprawną wartość i czy przyciski mają nazwę. To, czy użytkownicy rozumieją, dlaczego przycisk jest niedostępny, wymaga testu ręcznego.
Źródła
- W3C, Understanding 1.4.3 Contrast (Minimum): https://www.w3.org/WAI/WCAG22/Understanding/contrast-minimum.html
- W3C, Understanding 1.4.11 Non-text Contrast: https://www.w3.org/WAI/WCAG22/Understanding/non-text-contrast.html
- W3C WAI, APG Developing a Keyboard Interface (focusability of disabled controls): https://www.w3.org/WAI/ARIA/apg/practices/keyboard-interface/
- W3C WAI, APG Button pattern: https://www.w3.org/WAI/ARIA/apg/patterns/button/