Kryteria sukcesu WCAG · Level AAA

WCAG 2.4.12: Fokus nieprzesłonięty (rozszerzone)

- Przetłumaczę tekst z zachowaniem znaczenia, tonu i stylu. - Utrzymam oryginalne podziały na zdania i akapity. - Zachowam wszystkie liczby, odwołania do standardów i poziomów (AA, AAA). - Zadbam o poprawne, specjalistyczne słownictwo z zakresu dostępności. - Sprawdzę, czy tłumaczenie jest spójne i wierne oryginałowi. WCAG 2.4.12 wymaga, aby gdy komponent interfejsu użytkownika otrzymuje fokus z klawiatury, żadna część tego komponentu nie była zasłonięta przez treści utworzone przez autora — element z fokusem musi być w pełni widoczny. To rozszerzone kryterium (AAA) eliminuje dopuszczenie częściowej widoczności obecne w jego odpowiedniku na poziomie AA, zapewniając, że użytkownicy klawiatury zawsze dokładnie widzą, gdzie znajduje się fokus.

Co oznacza ta zasada

WCAG 2.4.12 — Focus Not Obscured (Enhanced) — jest odpowiednikiem na poziomie AAA dla WCAG 2.4.11 (Focus Not Obscured, AA). Podczas gdy kryterium AA dopuszcza, aby element w fokusie był częściowo widoczny, kryterium AAA wymaga, aby element w fokusie był całkowicie widoczny — żadna jego część nie może być zasłonięta przez treści stworzone przez autora w momencie, gdy element otrzymuje fokus z klawiatury.

W praktyce oznacza to, że gdy użytkownik przechodzi klawiszem Tab do elementu interaktywnego, takiego jak link, przycisk, pole formularza czy niestandardowy widżet, cały obszar ograniczający tego elementu musi być niezasłonięty przez jakikolwiek przyklejony nagłówek, stałą stopkę, nakładkę modalną, baner cookie, widżet czatu lub jakąkolwiek inną treść umieszczoną na stronie przez autora. Zasada dotyczy konkretnie treści stworzonych przez autora; W3C wprowadza wyraźny wyjątek dla treści, które użytkownik sam przesunął tak, by zasłaniały wskaźnik fokusu — na przykład pływający panel, który użytkownik przeciągnął przed element w fokusie. W takim przypadku autor nie ponosi odpowiedzialności.

Spełnienie kryterium 2.4.12 wymaga, aby po otrzymaniu fokusu cały element w fokusie był widoczny w obrębie okna przeglądarki i nie był zasłonięty przez żaden element o pozycjonowaniu sticky, fixed lub absolute, nad którym autor strony ma kontrolę. Niespełnienie kryterium ma miejsce, gdy jakakolwiek część widocznej granicy elementu w fokusie jest ukryta za takimi nakładkami — nawet pojedynczy piksel obramowania fokusu lub samego komponentu ucięty przez nakładkę jest na poziomie AAA traktowany jako błąd.

Ważne jest zrozumienie, czego 2.4.12 nie obejmuje. Nie narzuca konkretnego stylu wskaźnika fokusu (to jest uregulowane w 2.4.11 i 2.4.7). Nie wymaga, aby wskaźniki fokusu miały minimalny współczynnik kontrastu (to obejmuje 2.4.13). Odnosi się konkretnie do relacji przestrzennej między elementem w fokusie a inną treścią na stronie — problemu warstwowania, który najczęściej wynika z użycia pozycjonowania fixed i sticky w CSS.

Dotknięte kryterium elementy HTML obejmują każdy element fokusowalny lub dostępny z użyciem Tab: <a>, <button>, <input>, <select>, <textarea>, <details>, elementy z atrybutem tabindex oraz niestandardowe widżety interaktywne zbudowane z użyciem ról ARIA. Kryterium ma zastosowanie we wszystkich kontekstach przeglądania, w tym w iframe’ach, dialogach i podczas przejść między trasami w aplikacjach jednostronicowych (SPA).

Dlaczego to ma znaczenie

Nawigacja klawiaturą jest podstawową metodą dostępu dla szerokiej grupy użytkowników. Osoby z niepełnosprawnościami ruchowymi — w tym żyjące z takimi schorzeniami jak SLA, stwardnienie rozsiane, porażenie mózgowe czy urazy wynikające z powtarzalnego przeciążenia — polegają wyłącznie na klawiaturze lub urządzeniach przełącznikowych zamiast myszy. Osoby niewidome i słabowidzące korzystające z czytników ekranu również nawigują za pomocą klawiatury i chociaż ich technologie asystujące komunikują położenie fokusu głosowo, widzący użytkownicy klawiatury polegają całkowicie na wizualnym wskaźniku fokusu, aby zorientować się na stronie.

Gdy element w fokusie jest zasłonięty, nawet częściowo, użytkownicy ci doświadczają frustrującej i potencjalnie dezorientującej sytuacji: strona wydaje się nie oferować żadnego elementu w fokusie albo użytkownik musi zgadywać, gdzie znajduje się w dokumencie. Na poziomie AA (2.4.11) częściowa widoczność jest tolerowana — przynajmniej część komponentu jest widoczna, dając wskazówkę. Kryterium AAA całkowicie eliminuje ten kompromis, uznając, że nawet częściowo ukryty wskaźnik fokusu może zostać przeoczony przez użytkowników z obniżoną wrażliwością na kontrast, widzeniem tunelowym lub trudnościami poznawczymi, które utrudniają skanowanie ekranu.

Rozważmy konkretny scenariusz: turecka strona e-commerce używa stałego paska nawigacyjnego o wysokości 80px u góry okna oraz przyklejonego banera zgody na pliki cookie o wysokości 60px na dole. Użytkownik naciskający Tab, aby nawigować po kartach produktów, może zauważyć, że górna lub dolna krawędź karty w fokusie — włącznie z jej obramowaniem fokusu — wsunie się pod jedną z tych stałych powierzchni. Zgodnie z WCAG 2.4.11 (AA), jeśli jakakolwiek część karty jest nadal widoczna, strona spełnia kryterium. Zgodnie z 2.4.12 (AAA) cała karta musi być w pełni widoczna. To rozróżnienie ma znaczenie: częściowo ukryta etykieta przycisku w połączeniu z częściowo ukrytym obramowaniem fokusu może sprawić, że dla użytkownika słabowidzącego będzie faktycznie niemożliwe ustalenie, który element jest aktywny lub jaką akcję wykona.

Zgodnie z danymi Światowej Organizacji Zdrowia około 2,2 miliarda ludzi na świecie ma jakąś formę zaburzeń widzenia, a niepełnosprawności ruchowe dotyczą setek milionów kolejnych osób. Ulepszenia dostępności klawiaturowej przynoszą korzyści nie tylko tym grupom, ale także zaawansowanym użytkownikom, którzy preferują nawigację klawiaturą ze względu na szybkość, użytkownikom urządzeń bez wskaźnika (np. myszy) oraz osobom w sytuacjach, w których precyzyjna kontrola ruchowa jest tymczasowo ograniczona.

Poza dostępnością dla osób z niepełnosprawnościami, w pełni widoczny fokus poprawia ogólną użyteczność i zmniejsza koszty wsparcia. Gdy wszyscy użytkownicy — w tym osoby bez niepełnosprawności — mogą wyraźnie śledzić położenie fokusu, rośnie odsetek poprawnie wypełnianych formularzy, a liczba błędów maleje. Dla serwisów kierowanych do użytkowników w Turcji wykazanie zgodności z poziomem AAA sygnalizuje dojrzały program dostępności i buduje zaufanie zarówno wśród użytkowników, jak i zespołów odpowiedzialnych za zakupy instytucjonalne.

Powiązane reguły Axe-core

WCAG 2.4.12 jest sklasyfikowane jako wymagające testów manualnych i stanowi część dodatków WCAG 2.2. Nie istnieje w pełni zautomatyzowana reguła axe-core, która mogłaby wiarygodnie wykrywać to naruszenie, a zrozumienie przyczyn ma znaczenie dla zespołów budujących swoje potoki testowe.

  • Inspekcja manualna — focus-not-obscured-enhanced (brak reguły automatycznej): Automatyczne skanery dostępności, takie jak axe-core, działają na statycznym DOM lub migawce stanu renderowania. Wykrycie, czy element w fokusie jest zasłonięty, wymaga: (1) symulowania fokusu klawiatury na każdym elemencie interaktywnym po kolei, (2) obliczenia prostokąta ograniczającego element po przewinięciu wywołanym fokusem, (3) zidentyfikowania wszystkich elementów o pozycjonowaniu fixed i sticky oraz ich prostokątów ograniczających oraz (4) sprawdzenia nakładania się geometrycznego. Choć częściowa automatyzacja jest teoretycznie możliwa, dynamiczny charakter zachowania przewijania, CSS scroll-padding, płynnego przewijania i zarządzania fokusem przez JavaScript sprawia, że w praktyce jest to bardzo zawodne. Element w fokusie, który jest idealnie widoczny przy jednym rozmiarze okna, może być całkowicie zasłonięty przy innym. axe-core oznacza to kryterium jako wymagające oceny przez człowieka i oznacza wyniki jako „wymaga przeglądu”, a nie automatyczne naruszenia. Testerzy muszą ręcznie przejść klawiszem Tab przez każdy element interaktywny i wizualnie potwierdzić pełną widoczność przy każdej istotnej szerokości okna.
  • scrollable-region-focusable (reguła axe): Choć nie jest bezpośrednio mapowana na 2.4.12, ta reguła axe oznacza elementy wewnątrz obszarów przewijalnych, które są fokusowalne, ale mogą nie przewijać się poprawnie do widoku. Jest to powiązany sygnał wskazujący na problemy z zarządzaniem przewijaniem, które mogą powodować zasłanianie fokusu przez przyklejone nagłówki lub stopki — najczęstszy tryb błędu dla 2.4.12.

Ponieważ narzędzia automatyczne nie są w stanie wiarygodnie wychwycić naruszeń 2.4.12, organizacje muszą wbudować manualne przejścia klawiaturą w swój proces QA, najlepiej przy wielu szerokościach okna i z aktywnymi wszystkimi trwałymi warstwami interfejsu (paski nawigacyjne, widżety czatu, banery cookie, komunikaty RODO).

Jak testować

  1. Zautomatyzowany skan bazowy: Uruchom axe DevTools lub Lighthouse na stronie, aby zidentyfikować powiązane problemy, takie jak naruszenia scrollable-region-focusable lub problemy z przepełnieniem CSS. Te wyniki, choć nie są bezpośrednimi naruszeniami 2.4.12, wskazują obszary strony najbardziej narażone na problemy z zasłanianiem fokusu. W axe DevTools przefiltruj wyniki według kryteriów WCAG 2.2 i przejrzyj wszystkie pozycje „wymaga przeglądu” związane z widocznością fokusu.
  2. Identyfikacja całej trwałej treści nakładanej: Przed testami klawiatury wizualnie skataloguj każdy element z position: fixed lub position: sticky na stronie — zazwyczaj paski nawigacyjne, banery cookie, widżety czatu, pływające przyciski akcji i paski narzędzi w stopce. Zanotuj ich wysokości i położenie, aby wiedzieć, które strefy okna zajmują.
  3. Przejście nawigacji klawiaturą: Zaczynając od góry strony (lub po zamknięciu początkowego modala), wielokrotnie naciskaj Tab, aby przenosić fokus przez każdy element interaktywny. Na każdym zatrzymaniu fokusu sprawdź, czy cały element w fokusie — włącznie z widocznym wskaźnikiem fokusu (obramowaniem lub pierścieniem) — znajduje się w całości w niezasłoniętym obszarze okna. Nie akceptuj częściowej widoczności. Jeśli jakakolwiek część elementu lub jego obramowania fokusu znika za elementem stałym, zanotuj to jako naruszenie 2.4.12.
  4. Nawigacja wstecz: Powtórz przejście, używając Shift+Tab do nawigacji wstecz. Stałe stopki są często pomijane w testach tylko do przodu, ale mogą zasłaniać elementy podczas przechodzenia w odwrotnym kierunku.
  5. Testy z czytnikiem ekranu NVDA + Firefox: Uruchom NVDA, otwórz Firefox i nawiguj za pomocą Tab. Gdy NVDA ogłasza fokus na elemencie, wizualnie potwierdź, że element jest w pełni widoczny. Tryb fokusu NVDA nie przewija automatycznie elementów tak, aby były wolne od warstw stałych, więc naruszenia mogą różnić się od zachowania natywnego przeglądarki.
  6. Testy z czytnikiem ekranu VoiceOver + Safari (macOS/iOS): Włącz VoiceOver i używaj Tab (lub gestów przesunięcia na iOS) do nawigacji. Zarządzanie przewijaniem w Safari czasami różni się od Chromium, co może ujawnić stany zasłoniętego fokusu niewidoczne w Chrome.
  7. Testy w responsywnych szerokościach okna: Powtórz przejście klawiaturą przy typowych szerokościach — 320px, 768px, 1024px i 1440px. Elementy sticky często zmieniają wysokość lub położenie przy różnych punktach przerwania, zmieniając strefy ryzyka.
  8. Testy po interakcjach użytkownika: Otwórz menu rozwijane, rozwiń akordeony, wywołaj modale i przejdź do nowych tras w aplikacjach jednostronicowych. Po każdej zmianie stanu wznowij nawigację klawiszem Tab i ponownie zweryfikuj pełną widoczność fokusu, ponieważ treści dynamiczne często wprowadzają nowe stałe nakładki.

Jak naprawić

Przyklejony nagłówek zasłaniający linki w fokusie — niepoprawnie

<!-- Fixed header with no scroll compensation -->
<header style='position:fixed; top:0; height:80px; background:#fff; width:100%;'>
  <nav>...</nav>
</header>

<main>
  <!-- When Tab reaches this link near the top of main, the header covers it -->
  <a href='/products'>View all products</a>
</main>

Przyklejony nagłówek zasłaniający linki w fokusie — poprawnie

<!-- scroll-padding-top ensures focused elements scroll clear of the fixed header -->
<style>
  html {
    /* Match this value to the height of your fixed header */
    scroll-padding-top: 88px; /* 80px header + 8px breathing room */
  }
</style>

<header style='position:fixed; top:0; height:80px; background:#fff; width:100%;'>
  <nav>...</nav>
</header>

<main style='margin-top:80px;'>
  <!-- Focus now scrolls the element fully clear of the header -->
  <a href='/products'>View all products</a>
</main>

Baner cookie zasłaniający elementy interaktywne przy dolnej krawędzi okna — niepoprawnie

<!-- Cookie banner fixed to the bottom, no scroll compensation -->
<div id='cookie-banner' style='position:fixed; bottom:0; height:72px; width:100%; background:#222;'>
  <button>Accept All</button>
  <button>Manage Preferences</button>
</div>

<footer>
  <!-- These links at the bottom of the page get covered by the cookie banner -->
  <a href='/privacy'>Privacy Policy</a>
  <a href='/terms'>Terms of Service</a>
</footer>

Baner cookie zasłaniający elementy interaktywne przy dolnej krawędzi okna — poprawnie

<!-- Add scroll-padding-bottom and body padding to compensate for the banner height -->
<style>
  html {
    scroll-padding-bottom: 80px; /* 72px banner + 8px breathing room */
  }
  body {
    padding-bottom: 80px; /* Prevent content from being permanently under the banner */
  }
</style>

<div id='cookie-banner' style='position:fixed; bottom:0; height:72px; width:100%; background:#222;'>
  <button>Accept All</button>
  <button>Manage Preferences</button>
</div>

<footer>
  <!-- Links now scroll fully into the unobscured viewport area -->
  <a href='/privacy'>Privacy Policy</a>
  <a href='/terms'>Terms of Service</a>
</footer>

Zarządzanie fokusem w JavaScript bez uwzględnienia warstw stałych — niepoprawnie

<!-- SPA route change: focus moved to heading but scrollIntoView ignores header -->
<script>
function navigateTo(section) {
  const heading = document.querySelector('#' + section + ' h2');
  heading.setAttribute('tabindex', '-1');
  heading.focus();
  // scrollIntoView with no offset — heading scrolls behind fixed header
  heading.scrollIntoView({ behavior: 'smooth', block: 'start' });
}
</script>

Zarządzanie fokusem w JavaScript bez uwzględnienia warstw stałych — poprawnie

<!-- Use scroll-margin-top on the target element, or manually offset scrollY -->
<style>
  .focus-target {
    /* scroll-margin-top offsets this element's scroll position from the top */
    scroll-margin-top: 96px;
  }
</style>

<script>
function navigateTo(section) {
  const heading = document.querySelector('#' + section + ' h2');
  heading.setAttribute('tabindex', '-1');
  // scroll-margin-top on the element handles the visual offset automatically
  heading.classList.add('focus-target');
  heading.focus();
  // scrollIntoView now respects scroll-margin-top, clearing the fixed header
  heading.scrollIntoView({ behavior: 'smooth', block: 'start' });
}
</script>

Najczęstsze błędy

  • Ustawianie scroll-padding-top na body zamiast na html: Właściwość CSS scroll-padding musi być zastosowana do kontenera przewijania. Dla przewijania całej strony kontenerem przewijania jest element html, a nie body. Zastosowanie jej do body w większości przeglądarek nie ma żadnego efektu i jest jednym z najczęstszych błędów implementacyjnych.
  • Na sztywno ustawiona wartość w pikselach dla scroll-padding-top, która nie odpowiada rzeczywistej wysokości nagłówka we wszystkich punktach przerwania: Gdy nagłówek na urządzeniach mobilnych zwija się do mniejszej wysokości lub na desktopie rozszerza się o dodatkowy pasek nawigacyjny, statyczne przesunięcie staje się nieprawidłowe. Użyj niestandardowych właściwości CSS aktualizowanych przez JavaScript lub użyj calc() z jednostkami względnymi, aby utrzymać wartość w synchronizacji.
  • Zapominanie o scroll-margin-top na docelowych elementach kotwic w obrębie strony: Nawet gdy globalne scroll-padding-top jest poprawne dla nawigacji Tab, cele linków kotwicowych, które otrzymują fokus programowo (np. linki „skip”, nawigacja po hashach w SPA), mogą nadal lądować pod nagłówkiem, jeśli na tych konkretnych elementach nie ustawiono scroll-margin-top.
  • Zamykanie banera cookie bez ponownego testowania: Wiele zespołów testuje nawigację klawiaturą dopiero po zaakceptowaniu banera cookie. Ponieważ baner zajmuje dolną część okna, elementy fokusowalne zakotwiczone przy dolnej krawędzi mogą być zasłaniane tylko wtedy, gdy baner jest aktywny. Zawsze testuj przy wszystkich trwałych warstwach interfejsu w pełni wyświetlonych.
  • Testowanie tylko przy jednej szerokości okna: Elementy sticky często zmieniają wysokość, stają się widoczne lub całkowicie znikają przy różnych punktach przerwania. Błąd przy 375px może nie występować przy 1440px i odwrotnie. Testowanie tylko w jednym rozmiarze pomija znaczną część rzeczywistych naruszeń.
  • Używanie overflow: hidden na kontenerze nadrzędnym do przycinania wskaźników fokusu: Gdy komponent karty lub kontener ma overflow: hidden, domyślne obramowanie fokusu przeglądarki na elementach potomnych jest przycinane na granicy kontenera. Może to sprawić, że fokus będzie wydawał się w pełni widoczny w inspekcji elementów w DevTools, podczas gdy dla użytkownika będzie wizualnie ucięty.
  • Zakładanie, że czytniki ekranu automatycznie obsługują przewijanie, więc testy wizualne są zbędne: Choć czytniki ekranu ogłaszają element w fokusie głosowo, widzący użytkownicy klawiatury — w tym osoby korzystające z narzędzi powiększających ekran — polegają całkowicie na położeniu wizualnym. Wizualnie zasłonięty stan fokusu jest realnym naruszeniem niezależnie od zachowania czytnika ekranu.
  • Brak testowania okien modalnych i paneli wysuwanych: Gdy otwiera się modal i fokus zostaje przeniesiony do jego wnętrza, tło lub sam interfejs modala może zasłaniać pierwszy element w fokusie w dialogu. Jest to szczególnie częste w panelach typu „drawer”, które wysuwają się z boku lub od dołu.
  • Ignorowanie widżetów zewnętrznych, takich jak dymki czatu na żywo i banery reklamowe typu interstitial: Pływające widżety czatu (np. Intercom, Zendesk) oraz stałe banery promocyjne wstrzykiwane przez menedżery tagów są treściami stworzonymi przez autora i mieszczą się w zakresie tego kryterium. Zespoły często je pomijają, ponieważ są zarządzane poza główną bazą kodu.
  • Poleganie wyłącznie na automatycznych skanach dostępności i zamykanie zgłoszenia: Ponieważ 2.4.12 wymaga testów manualnych, czysty skan axe-core nie potwierdza zgodności. Zamykanie zgłoszeń dotyczących dostępności wyłącznie na podstawie wyników automatycznych będzie konsekwentnie pomijać to kryterium.

Związek z tureckimi regulacjami dotyczącymi dostępności

Turecka Okrężnica Prezydencka 2025/10, opublikowana w Dzienniku Urzędowym nr 32933 w dniu 21 czerwca 2025, ustanawia wiążące wymagania dotyczące dostępności stron internetowych i aplikacji mobilnych dla szerokiego zakresu podmiotów działających w Turcji. Okrężnica przyjmuje WCAG 2.1 na poziomie AA jako podstawowy standard zgodności, co oznacza, że WCAG 2.4.12 — jako kryterium WCAG 2.2 na poziomie AAA — nie jest bezpośrednio wymagane na mocy obecnych przepisów. Niemniej jednak jego związek z tureckimi ramami dostępności ma znaczenie z kilku powodów.

Podmioty objęte Okrężnicą Prezydencką 2025/10 obejmują instytucje publiczne i organy rządowe na wszystkich szczeblach, platformy e-commerce, banki i dostawców usług finansowych, szpitale i organizacje ochrony zdrowia, firmy telekomunikacyjne z 200 000 lub większą liczbą abonentów, biura podróży, prywatne firmy transportowe oraz szkoły prywatne upoważnione przez Ministerstwo Edukacji Narodowej (MoNE). Dla wszystkich tych organizacji osiągnięcie zgodności z WCAG 2.1 AA jest obowiązkiem prawnym, a oczekuje się, że okrężnica będzie egzekwowana poprzez mechanizmy audytu administrowane przez właściwe organy nadzorcze.

Choć zgodność z poziomem AAA nie jest wymagana przez okrężnicę, organizacje w sektorach regulowanych mają silne praktyczne powody, aby dążyć do spełnienia WCAG 2.4.12. Po pierwsze, tureckie otoczenie regulacyjne ewoluuje: okrężnica stanowi istotne zaostrzenie egzekwowania dostępności w porównaniu z wcześniejszymi wytycznymi, a przyszłe nowelizacje mogą przyjąć WCAG 2.2 lub podnieść poziom zgodności. Organizacje, które już teraz wdrożą praktyki na poziomie AAA, będą lepiej przygotowane na zmiany regulacyjne. Po drugie, procesy zamówień publicznych i dostęp do rynku UE coraz częściej premiują dostawców, którzy mogą wykazać rozbudowane programy dostępności, a dokumentacja zgodności z poziomem AAA stanowi przewagę konkurencyjną.

Po trzecie, i najbardziej bezpośrednio w odniesieniu do WCAG 2.4.12, kryterium to dotyczy trybu błędu, który w nieproporcjonalny sposób dotyka użytkowników technologii asystujących w Turcji — populacji szacowanej na kilka milionów osób, jeśli zliczyć łącznie niepełnosprawności ruchowe, wzrokowe i poznawcze. Banki, szpitale i portale e-administracji, które w dużym stopniu polegają na stałych elementach nawigacyjnych i trwałych warstwach powiadomień, są dokładnie tymi serwisami, w których błędy związane z zasłanianiem fokusu występują najczęściej. Inwestowanie w pełną zgodność z WCAG 2.4.12 pokazuje rzeczywiste zaangażowanie w obsługę wszystkich użytkowników, jest zgodne z duchem okrężnicy prezydenckiej, nawet jeśli jej litera jeszcze tego nie wymaga, oraz zmniejsza ryzyko prawne i reputacyjne w miarę dojrzewania systemu egzekwowania przepisów w Turcji.

Dla organizacji korzystających z Accsible overlay SDK platforma zapewnia narzędzia do audytu ścieżek fokusu klawiatury i identyfikowania konfliktów wynikających z pozycjonowania sticky, wspierając zarówno obowiązkowe wymagania poziomu AA z Okrężnicy Prezydenckiej 2025/10, jak i dobrowolne ulepszenia na poziomie AAA, takie jak WCAG 2.4.12.