WCAG 2.4.13: Wygląd fokusu
Kryterium sukcesu WCAG 2.4.13: Wygląd fokusu (Nieprzesłonięty – Minimum) koncentruje się na fundamentalnym aspekcie nawigacji klawiaturą – widoczności wskaźnika fokusu. Wskaźnik fokusu to wizualna wskazówka, która informuje użytkownika, który element interfejsu (np. link, przycisk, pole formularza) jest aktualnie aktywny i gotowy do interakcji. To kryterium, wprowadzone w WCAG 2.2, ma na celu zapewnienie, że ten wskaźnik nie jest zasłaniany przez inne elementy strony, co jest kluczowe dla wszystkich użytkowników nawigujących za pomocą klawiatury.
Chociaż podana nazwa "Wygląd fokusu" oraz rozszerzony opis "Wskaźnik fokusu powinien być wyraźny, odpowiednio duży i kontrastowy, aby był łatwo widoczny" odnoszą się do ogólnej jakości wskaźnika fokusu (pokrywanej również przez WCAG 2.4.7 Widoczność fokusu i 2.4.11 Wygląd fokusu (Minimum)), kryterium 2.4.13 skupia się konkretnie na problemie zasłaniania. Niewidoczny lub częściowo zasłonięty wskaźnik fokusu, niezależnie od jego kontrastu czy rozmiaru, stanowi barierę w dostępności.
Czym jest WCAG 2.4.13: Wygląd fokusu (Nieprzesłonięty – Minimum)?
WCAG 2.4.13 wymaga, aby wskaźnik fokusu, gdy element interfejsu otrzyma klawiszowy fokus, nie był całkowicie ukryty przez treść utworzoną przez autora strony. Oznacza to, że żadne elementy statyczne (takie jak nagłówki "sticky", stopki, boczne paski) ani dynamiczne (takie jak wyskakujące okienka, modale, powiadomienia) nie powinny całkowicie zasłaniać wizualnego wskaźnika fokusu.
- Wymóg: Wskaźnik fokusu musi być widoczny i niezasłonięty, gdy element interfejsu otrzyma fokus klawiatury. Nawet częściowe zasłonięcie może być problematyczne, choć kryterium mówi o "całkowitym" ukryciu. Dobre praktyki zdecydowanie zalecają pełną widoczność.
- Cel: Umożliwienie użytkownikom klawiatury śledzenia, gdzie aktualnie znajduje się ich fokus, co pozwala im zrozumieć kontekst i przewidzieć wynik interakcji.
Dlaczego to jest ważne? (Wpływ na dostępność)
Zasłonięty wskaźnik fokusu stanowi poważną barierę dla wielu grup użytkowników:
- Użytkownicy klawiatury: Osoby, które nie mogą lub nie chcą używać myszy (np. z powodu niepełnosprawności ruchowej, tymczasowej kontuzji, braku myszy), polegają wyłącznie na klawiaturze do nawigacji. Bez widocznego wskaźnika fokusu, nie wiedzą, który element jest aktywny, co uniemożliwia im korzystanie z witryny.
- Użytkownicy z niepełnosprawnościami poznawczymi: Osoby z pewnymi rodzajami niepełnosprawności poznawczych (np. zaburzenia koncentracji, problemy z pamięcią krótkotrwałą) potrzebują wyraźnych wizualnych wskazówek, aby utrzymać orientację na stronie. Zasłonięty fokus prowadzi do frustracji, dezorientacji i niemożności wykonania zadania.
- Użytkownicy czytników ekranu: Chociaż czytniki ekranu odczytują aktywny element, wielu użytkowników czytników ekranu (szczególnie tych z resztkowym wzrokiem) nadal korzysta z wizualnych wskaźników fokusu jako dodatkowej pomocy w orientacji na stronie.
Brak widocznego fokusu przekłada się na brak możliwości interakcji, co skutecznie wyklucza użytkowników z korzystania z witryny lub aplikacji.
Szczegółowe wymagania kryterium sukcesu
Oto dokładne brzmienie kryterium sukcesu 2.4.13:
- Kryterium sukcesu 2.4.13: Wygląd fokusu (Nieprzesłonięty – Minimum) (Poziom AA)
Gdy element interfejsu użytkownika otrzyma fokus klawiatury, wskaźnik fokusu nie jest całkowicie ukryty przez treść utworzoną przez autora.
Należy zauważyć, że kryterium to dotyczy "całkowitego" ukrycia. Jednak w praktyce nawet częściowe ukrycie jest złym doświadczeniem użytkownika i często prowadzi do trudności w nawigacji. Dobre praktyki zalecają, aby wskaźnik fokusu był zawsze w pełni widoczny.
Praktyczne wskazówki dla zapewnienia zgodności
Aby spełnić kryterium 2.4.13, należy zwrócić uwagę na projekt i implementację elementów, które mogą zasłaniać fokus:
- Unikaj nakładających się elementów: Zadbaj o to, aby elementy interfejsu nie nakładały się w sposób, który uniemożliwia widoczność fokusu. Dotyczy to szczególnie elementów z pozycjonowaniem absolutnym lub stałym.
- Zarządzanie elementami "sticky" (przyklejonymi): Nagłówki, stopki lub boczne paski z pozycjonowaniem
position: fixed;
lubposition: sticky;
są częstą przyczyną zasłaniania fokusu. Upewnij się, że te elementy mają odpowiedniz-index
i/lub używaj marginesów/paddingów, aby treść przechodząca pod nimi nie była zasłonięta, a wskaźnik fokusu był zawsze widoczny. Możesz też dynamicznie dostosowywać przewijanie, aby fokus był zawsze w widocznym obszarze (patrz "scroll-margin"). - Modale i wyskakujące okienka: Kiedy pojawia się modalne okienko, fokus powinien być przeniesiony do niego, a po zamknięciu – zwrócony do elementu, który otworzył modal. Co ważniejsze, samo modalne okienko nie powinno zasłaniać wskaźnika fokusu dla elementów interaktywnych znajdujących się wewnątrz niego. Treść pod modalem nie powinna być interaktywna, a jeśli jest, jej fokus nie powinien być dostępny.
- Użycie
z-index
: Prawidłowe zarządzanie warstwami za pomocą właściwości CSSz-index
jest kluczowe. Elementy interaktywne i ich wskaźniki fokusu powinny mieć odpowiednio wysokiz-index
, aby nie były zasłaniane przez tło lub elementy dekoracyjne. - Programowe zarządzanie przewijaniem: W niektórych złożonych interfejsach może być konieczne programowe przewijanie strony, aby zapewnić, że element z fokusem jest zawsze w widocznym obszarze (np. używając
element.focus({ preventScroll: false });
lubelement.scrollIntoView()
).
Przykłady implementacji
Przykłady poprawne
Wskaźnik fokusu widoczny i niezasłonięty
W tym przykładzie nagłówek strony jest stały, ale jego wysokość jest uwzględniona w stylach dla treści, dzięki czemu wskaźnik fokusu nie jest zasłaniany.
<style>
body {
margin: 0;
font-family: Arial, sans-serif;
}
.header {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 60px;
background-color: #333;
color: white;
display: flex;
align-items: center;
padding: 0 20px;
box-sizing: border-box;
z-index: 1000;
}
.content {
padding-top: 80px; /* Zapewnia miejsce pod nagłówkiem */
padding-bottom: 20px;
}
a:focus, button:focus {
outline: 3px solid blue;
outline-offset: 2px;
}
/* Użycie scroll-margin-top dla lepszej kontroli przewijania */
:focus-visible {
scroll-margin-top: 80px; /* Wyrównuje fokus pod stałym nagłówkiem (wysokość nagłówka + padding) */
}
</style>
<div class="header">Stały Nagłówek</div>
<div class="content">
<p>Początek treści strony.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
<p>Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<p><a href="#">Link do kliknięcia (fokus)</a></p>
<p>Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt.</p>
<p><button>Przycisk (fokus)</button></p>
<p>Koniec treści strony.</p>
</div>
W powyższym przykładzie, padding-top
na elemencie .content
zapobiega zachodzeniu treści pod stały nagłówek. Dodatkowo, scroll-margin-top
na :focus-visible
zapewnia, że przeglądarka przewinie stronę w taki sposób, aby element z fokusem był widoczny poniżej nagłówka, a nie pod nim.
Przykłady niepoprawne
Wskaźnik fokusu zasłonięty przez nagłówek "sticky"
W tym scenariuszu stały nagłówek strony całkowicie zakrywa wskaźnik fokusu, gdy użytkownik przewija stronę i nawiguje klawiaturą.
<style>
body {
margin: 0;
font-family: Arial, sans-serif;
}
.header {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 60px;
background-color: red; /* Podkreślenie problemu */
color: white;
display: flex;
align-items: center;
padding: 0 20px;
box-sizing: border-box;
z-index: 1000;
}
.content {
/* Brak padding-top lub niewystarczający, co prowadzi do zasłaniania */
padding-top: 10px;
padding-bottom: 20px;
}
a:focus, button:focus {
outline: 3px solid blue;
outline-offset: 2px;
}
</style>
<div class="header">Problemowy Nagłówek</div>
<div class="content">
<p>Początek treści strony.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
<p>Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<p><a href="#">Link, którego fokus może być zasłonięty</a></p>
<p>Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt.</p>
<p><button>Przycisk, którego fokus może być zasłonięty</button></p>
<p>Koniec treści strony.</p>
</div>
W tym przykładzie, jeśli użytkownik przewinie stronę i element interaktywny znajdzie się na górze widocznego obszaru, jego wskaźnik fokusu zostanie ukryty przez czerwony, stały nagłówek. Jest to bezpośrednie naruszenie WCAG 2.4.13.
Wskaźnik fokusu zasłonięty przez modalne okienko
Wyobraź sobie, że po aktywacji przycisku, pojawia się modalne okienko, które nie łapie fokusu, a zamiast tego fokus pozostaje na elemencie pod spodem lub przemieszcza się na elementy interaktywne pod modalem, które są wizualnie zasłonięte.
<style>
.modal-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.7);
display: none; /* Domyślnie ukryte */
justify-content: center;
align-items: center;
z-index: 2000;
}
.modal-content {
background-color: white;
padding: 20px;
border-radius: 5px;
}
.main-content button:focus, .main-content a:focus {
outline: 3px solid blue;
outline-offset: 2px;
}
.show-modal {
display: flex;
}
</style>
<div class="main-content">
<button id="openModalBtn">Otwórz Modal</button>
<p>Treść główna strony.</p>
<p><a href="#">Link pod modalem</a></p>
<p>Dalsza treść.</p>
</div>
<div class="modal-overlay" id="myModal">
<div class="modal-content">
<p>To jest modal.</p>
<button id="closeModalBtn">Zamknij</button>
</div>
</div>
<script>
const openBtn = document.getElementById('openModalBtn');
const closeBtn = document.getElementById('closeModalBtn');
const modal = document.getElementById('myModal');
const mainContent = document.querySelector('.main-content');
openBtn.addEventListener('click', () => {
modal.classList.add('show-modal');
mainContent.setAttribute('aria-hidden', 'true'); // Wizualnie zasłonięte elementy są też ukryte dla czytników
closeBtn.focus(); // Przeniesienie fokusu do modalu
});
closeBtn.addEventListener('click', () => {
modal.classList.remove('show-modal');
mainContent.removeAttribute('aria-hidden');
openBtn.focus(); // Zwrócenie fokusu
});
// Problem: W tym przykładzie, jeśli nie uwięzimy fokusu wewnątrz modalu
// (np. przez naciśnięcie klawisza Tab, aby przejść na 'Link pod modalem'),
// fokus może nadal opuścić modal i aktywować elementy pod spodem, które są wizualnie zasłonięte.
// Poprawne rozwiązanie wymagałoby bardziej zaawansowanego zarządzania fokusem (focus trap).
</script>
W tym niepoprawnym przykładzie, nawet jeśli fokus zostanie początkowo przeniesiony do modalu, bez mechanizmu "focus trap" (uwięzienia fokusu) użytkownik klawiatury może opuścić modal (np. naciskając Tab
wielokrotnie), a fokus powędruje na elementy pod spodem. Ich wskaźnik fokusu będzie całkowicie zasłonięty przez modal, co jest naruszeniem WCAG 2.4.13. Poprawna implementacja wymaga upewnienia się, że elementy poza modalem są nieinteraktywne i niedostępne dla fokusu klawiatury, a fokus jest cyklicznie utrzymywany wewnątrz modalu.
Dobre praktyki i typowe pułapki
- Testowanie z klawiaturą: Regularne testowanie całej strony za pomocą samej klawiatury (klawisz Tab, Shift+Tab, Enter, Spacja, klawisze strzałek) jest najskuteczniejszym sposobem na wykrycie problemów z widocznością fokusu.
- Responsywny design: Elementy, które wyglądają dobrze na dużych ekranach, mogą powodować problemy na mniejszych urządzeniach. Testuj swoją stronę na różnych rozmiarach ekranu, aby upewnić się, że responsywne układy nie zasłaniają wskaźnika fokusu.
- Dynamiczne zmiany treści: Upewnij się, że po dynamicznych zmianach treści (np. załadowaniu nowych elementów, wyświetleniu komunikatów) wskaźnik fokusu nadal jest widoczny i nie jest zasłonięty przez nowo pojawiające się elementy.
- Wykorzystaj
:focus-visible
: Pseudoklasa CSS:focus-visible
pozwala na stylizowanie fokusu tylko wtedy, gdy przeglądarka uzna, że jest to użyteczne (np. dla użytkowników klawiatury, ale nie dla kliknięć myszą). Pamiętaj, aby zawsze zapewnić domyślny lub niestandardowy styl fokusu, który spełnia kryteria dostępności. - Unikaj
outline: none;
: Nadpisanie domyślnego wskaźnika fokusu za pomocąoutline: none;
bez zapewnienia alternatywnego, widocznego i niezasłoniętego wskaźnika jest jedną z najczęstszych pułapek i bezpośrednio prowadzi do naruszenia WCAG. - Zarządzanie fokusem w JS: W przypadku niestandardowych komponentów UI lub złożonych interakcji, możesz potrzebować JavaScriptu do programowego zarządzania fokusem (np. przenoszenie fokusu, uwięzienie fokusu w modalach). Upewnij się, że takie zarządzanie jest zgodne z oczekiwaniami użytkowników klawiatury i nie prowadzi do ukrywania fokusu.
Podsumowanie
Kryterium sukcesu WCAG 2.4.13: Wygląd fokusu (Nieprzesłonięty – Minimum) jest niezbędne do zapewnienia, że użytkownicy klawiatury mogą efektywnie nawigować i wchodzić w interakcję z treścią. Projektowanie z myślą o tym, aby wskaźnik fokusu był zawsze w pełni widoczny i niezasłonięty przez inne elementy interfejsu, to fundamentalny element tworzenia inkluzywnych i dostępnych stron internetowych. Pamiętając o tych wytycznych, możemy znacząco poprawić użyteczność i dostępność naszych aplikacji i witryn dla wszystkich.