1.4.13Poziom AA

Treść po najechaniu lub otrzymaniu fokusu

Content on Hover or Focus

Dodatkową treść wywołaną najechaniem lub fokusem można ukryć, najechać na nią i czytać bez wymuszonego znikania, z określonymi wyjątkami.

Komu pomaga
SłabowidzenieOgraniczenia ruchowePamięć i koncentracja
Zastosowanie
WWWAplikacje mobilneAplikacje desktopoweDokumenty cyfroweInne urządzenia

Warunki i wyjątki opisano w artykule.

Wersja
WCAG 2.2, wprowadzone w 2.1
Zasada / wytyczna
Postrzegalność / 1.4
Stan researchu
Draft AI. Bez przeglądu człowieka.
Redakcja artykułu
· wersja robocza
Na tej stronie

Co oznacza to kryterium

Instrukcja pojawiająca się po najechaniu wskaźnikiem lub otrzymaniu fokusu powinna dać czas na czytanie. Jeśli najechanie ją wywołuje, można przesunąć wskaźnik na samą instrukcję bez jej zniknięcia. Jeśli zasłania inne informacje, trzeba móc ją ukryć bez opuszczania wyzwalacza, z opisanym niżej wyjątkiem błędu danych.

Pomaga to osobom słabowidzącym korzystającym z powiększenia lub dużego wskaźnika, osobom z ograniczeniami ruchowymi oraz osobom potrzebującym więcej czasu na przeczytanie. Nie trzeba utrzymywać wskaźnika na małym celu ani wykonywać szybkiego przejścia. Sama rola tooltip, przycisk zamknięcia lub obecność tekstu w drzewie dostępności nie potwierdzają zachowania.

Przykłady błędów i poprawek

Ukrycie instrukcji bez utraty fokusu

Pracownia pokazuje syntetyczny odbiór P-104 na 6 października, 16:00–18:00. Ta sama instrukcja brzmi: „Wejdź od ogrodu i podaj kod P-104. Zabierz dokument odbioru. Nie korzystaj z wejścia od ulicy.” Próbka niczego nie wysyła.

Bad nakłada instrukcję na termin i nie pozwala jej ukryć bez opuszczenia pola lub wyzwalacza. Good dodaje mechanizm zamknięcia: na iOS tap „Ukryj instrukcję” pozostawia fokus pola, w przeglądarce działa Escape lub aktywacja wyzwalacza. Brak timera daje użytkownikowi czas na odczytanie.

  1. Ustaw fokus pola kodu w natywnej próbce. Instrukcja zasłania termin.
  2. W good aktywuj „Ukryj instrukcję”. Panel znika i odsłania termin, a pole zachowuje primary focus.
  3. Wpisz P-104 bez ponownego tapnięcia pola. Źródłowy XCTest potwierdził ten przebieg; nie był to test zewnętrznej klawiatury ani czytnika.
Pracownia na iOS, bad: panel instrukcji pod polem kodu zasłania termin odbioru i nie ma zamknięcia.

Surowy końcowy kadr 2026-10-04, Flutter/Cupertino, iPhone 17 Simulator. Ramka panelu y 231–314 nakłada się na termin y 255–281. Rzeczywisty primary focus potwierdza odczyt FocusNode; sam obraz tego nie dowodzi.

Pracownia na iOS, good po zamknięciu instrukcji: widoczny termin, kursor w polu i otwarta klawiatura.

Ten sam kontekst po zwykłym tapnięciu zamknięcia. Panel zniknął, pole zachowało primary focus, a kolejne typeText wpisało P-104. Obserwacja dotyczy gałęzi wywołanej fokusem po tapnięciu; native hover, Escape i FKA niewykonane.

Wskaźnik przechodzi na dodatkową treść

W przeglądarce bad ukrywa panel już przy opuszczeniu wyzwalacza w kierunku instrukcji. Good i control utrzymują panel w sumie obszarów wyzwalacza i treści. Bad/good różnią się także zamknięciem: nie jest to izolowany eksperyment jednej przyczyny. Każdy z trzech warunków trzeba ocenić oddzielnie.

Pracownia w przeglądarce, good: instrukcja pozostaje po przejściu wskaźnika na jej tekst.

Surowy JPEG 1280×720 z 2026-10-04. Szare zaznaczenie powstało podczas rzeczywistego przeciągania, bez retuszu; nie oznacza fokusu. Część ruchu miała wciśnięty przycisk myszy, więc zapis nie zastępuje swobodnego ruchu fizycznej myszy.

Pracownia w przeglądarce, bad: po przejściu od wyzwalacza w kierunku instrukcji panel zniknął i odsłonił termin.

Ten sam scenariusz i dane. Zniknięcie dokumentują także odczyty zdarzeń i stanu; pojedynczy obraz nie dowodzi całej ścieżki wskaźnika.

Panel, który nie zasłania innych informacji

Control nie ma zamknięcia, ale termin znajduje się poniżej instrukcji. W zmierzonym widoku panel nie zasłania wyzwalacza ani innych informacji. Korzysta z wyjątku dotyczącego możliwości ukrycia; nadal musi pozostać widoczny i pozwolić na najechanie, jeśli hover jest wyzwalaczem. Po powiększeniu lub zmianie układu trzeba ponownie ustalić, czy nie pojawia się zasłanianie.

Pracownia na iOS, control: panel instrukcji nad terminem, bez nakładania i bez przycisku zamknięcia.

Końcowy kadr z 2026-10-04. Panel y 231–314, termin y 395–421; źródłowe ramki i obraz potwierdzają brak nakładania tylko w tym widoku. Nie wykonano próby powiększenia.

Kiedy obowiązuje i gdzie są wyjątki

Trzy warunki oceniane osobno

Warunek Wymagane zachowanie Granice i wyjątki
Możliwość ukrycia — dismissible Dodatkową treść można zamknąć bez przesunięcia wskaźnika lub fokusu z wyzwalacza. Zamknięcie nie jest wymagane, gdy treść zgłasza błąd danych albo nie zasłania i nie zastępuje innej treści, także wyzwalacza.
Możliwość najechania — hoverable Jeśli najechanie może wywołać treść, wskaźnik może przejść na nią bez zniknięcia. Dotyczy także panelu wywoływanego równolegle fokusem. Dla treści wyłącznie po fokusie nie trzeba tworzyć sztucznego hover.
Utrzymanie widoczności — persistent Treść pozostaje do usunięcia hover/fokusu z wyzwalacza i dodatkowej treści, świadomego zamknięcia lub rzeczywistej nieaktualności informacji. Opuszczenie samego wyzwalacza przy wskaźniku na panelu nie wystarcza. Arbitralny timer 5, 30 lub 60 sekund nie jest zgodny tylko dlatego, że wydaje się długi.

Wyjątek ogólny obejmuje dodatkową treść, której prezentacją steruje przeglądarka lub platforma i której autor nie zmodyfikował, np. systemowy tooltip title. Własny popover nie otrzymuje tego wyjątku przez samo użycie API platformy.

Kryterium dotyczy dodatkowej treści względem wyzwalacza. Link pomijania, który sam ujawnia się po fokusie, nie jest takim panelem. Ujawnienie wyłącznie świadomym kliknięciem nie spełnia warunku hover/focus, ale nie przesądza innych wymagań. Modal wymagający przeniesienia fokusu wykracza poza ten wzorzec; jego samoistne otwarcie może podlegać 3.2.1.

SCR39 opisuje trzy zachowania, osobno dla hover i fokusu. F95 dotyczy znikania przy przejściu wskaźnika na treść; nie zastępuje oceny zamknięcia i trwałości. W researchu z 2026-10-04 pomysły ARIA tooltip, CSS hover/focus i dodatkowe opisy błędów miały status potencjalnych przyszłych technik. Sama rola lub pseudoklasa nie jest wystarczającym dowodem. Katalog ACT odczytany tego dnia nie zawierał reguły dla 1.4.13; nie deklarujemy formalnego wyniku ACT.

Platformy

Ocena AI z 2026-10-04: wszędzie zastosowanie jest warunkowe — dodatkowa treść autora pojawia się i znika po otrzymaniu/usunięciu hover lub fokusu. Nieprzetestowana platforma pozostaje objęta oceną warunku. Dotyk sam nie wyłącza kryterium.

Środowisko Podstawa i adaptacja Wykonanie w źródle
WWW, także w telefonie WCAG 2.2, 1.4.13; bez zmiany wymagania. HTML/CSS/JS w IAB na macOS: fokus i ograniczony ruch wskaźnika.
Aplikacje mobilne Informacyjna WCAG2ICT 2.2, Group Note 2025-12-11; dodatkowa treść natywna, terminy dokumentu/oprogramowania i platformowego UI. Flutter/Cupertino iOS: fokus pola po tap, ukrycie i dalsze wpisywanie. Hover i zewnętrzna klawiatura niewykonane.
Aplikacje desktopowe Ta sama WCAG2ICT; kontrolka wywołująca panel przez hover lub fokus, wyjątek niemodyfikowanej prezentacji platformy. Niewykonane; przeglądarka macOS jest wykonaniem części webowej.
Dokumenty cyfrowe Ta sama WCAG2ICT; interaktywny dokument z takim mechanizmem. Statyczny PDF bez niego nie dotyczy tylko danego scenariusza. Niewykonane.
Inne interfejsy ICT Ta sama WCAG2ICT; oceń konkretny interfejs oprogramowania, nie sam sprzęt. Niewykonane.

WCAG2ICT rozszerza user agent o oprogramowanie platformy, title o atrybuty obiektu UI, link o podobne kontrolki, a stronę o dokument poza WWW lub oprogramowanie. To wskazówka interpretacyjna, bez samodzielnej deklaracji prawnej. Nie oceniano EN 301 549 ani obowiązku prawnego; w hybrydzie część HTML ocenia się osobno od natywnej.

Rozwiązania w technologiach

Oficjalną dokumentację API przejrzano przez AI 2026-10-04. Flutter i stronę HTML uruchomiono w opisanym zakresie. SwiftUI, Compose i React Native są fragmentami edukacyjnymi bez kompilacji i działania. Build Fluttera nie potwierdza pozostałych technologii.

Flutter

Fragment wymaga package:flutter/cupertino.dart i package:flutter/services.dart, stanu widoku, listenera aktualizującego UI oraz dispose obu węzłów. Listener po utracie fokusu zeruje dismissed; panel renderuje się warunkowo według shown. Zamknięcie nie wywołuje unfocus ani requestFocus.

final codeFocus = FocusNode(debugLabel: 'pickup-code');
final passiveClose = FocusNode(canRequestFocus: false);
bool dismissed = false;
bool get shown => codeFocus.hasFocus && !dismissed;
// Listener: setState; po utracie codeFocus.hasFocus dismissed = false.
// Pole: CupertinoTextField(focusNode: codeFocus).
// Dodatkowa treść renderowana warunkowo przez shown.
CupertinoButton(
  focusNode: passiveClose,
  onPressed: () => setState(() => dismissed = true),
  child: const Text('Ukryj instrukcję'),
)

Focus ancestor może obsłużyć Escape, lecz obecność handlera nie potwierdza wykonanego natywnego testu klawisza. canRequestFocus: false zachowuje fokus podczas tapnięcia; nie dowodzi osiągalności zamknięcia przez klawiaturę lub AT. Hover wymaga stanu wspólnego obszaru, np. MouseRegion wyzwalacza i panelu. Zamknięcie na onExit samego wyzwalacza odtwarza problem.

Flutter 3.44.9 / Dart 3.12.2: analiza, host, build i focus-only iOS PASS. Hover, FKA i Escape na urządzeniu niewykonane.

iOS / SwiftUI

import SwiftUI
struct PickupHelp: View {
    let instruction: String
    @State private var code = ""
    @State private var dismissed = false
    @FocusState private var codeFocused: Bool
    var body: some View {
        VStack(alignment: .leading) {
            TextField("Kod odbioru", text: $code).focused($codeFocused)
            if codeFocused && !dismissed {
                Text(instruction)
                Button("Ukryj instrukcję") { dismissed = true }
            }
            Text("Odbiór: 6 października, 16:00–18:00.")
        }.onChange(of: codeFocused) { _, focused in
            if !focused { dismissed = false }
        }
    }
}

Panel w przepływie nie przykrywa terminu; w takim widoku korzysta z wyjątku dismissible. Opcjonalne zamknięcie nie ustawia codeFocused = false, ale bez runtime nie potwierdzamy zachowania Button przy tap. Dla nakładki zapewnij zamknięcie bez utraty rzeczywistego fokusu. onHover powinien objąć wspólny region, a świadome ukrycie resetować dopiero po opuszczeniu obu treści; fokus nadal utrzymuje panel niezależnie od hover. Dokumentacja przejrzana; kompilacja i działanie niewykonane.

Android / Jetpack Compose

import androidx.compose.foundation.layout.Column
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.onFocusChanged
import androidx.compose.ui.input.key.*

@Composable
fun PickupHelp(instruction: String) {
    var code by remember { mutableStateOf("") }
    var focused by remember { mutableStateOf(false) }
    var dismissed by remember { mutableStateOf(false) }
    Column {
        TextField(code, { code = it }, label = { Text("Kod odbioru") },
            modifier = Modifier.onFocusChanged {
                focused = it.isFocused
                if (!focused) dismissed = false
            }.onPreviewKeyEvent {
                if (focused && !dismissed && it.key == Key.Escape &&
                    it.type == KeyEventType.KeyDown) {
                    dismissed = true
                    true
                } else false
            })
        if (focused && !dismissed) Text(instruction)
        Text("Odbiór: 6 października, 16:00–18:00.")
    }
}

Fragment focus-only umieszcza pomoc w Column, bez zakrywania terminu. Preview obsługuje Escape bez żądania nowego fokusu; onFocusChanged tylko obserwuje stan. Hover nie jest zaimplementowany. Dla nakładki i wskaźnika rozszerz stan i zbadaj właściwy odbiornik. Dokumentacja przejrzana; kompilacja i działanie niewykonane, bez potwierdzenia przekazania Escape przez konkretny system.

React Native

import React, { useState } from 'react';
import { ScrollView, Text, TextInput, Pressable } from 'react-native';
export function PickupHelp({ instruction }: { instruction: string }) {
  const [focused, setFocused] = useState(false);
  const [dismissed, setDismissed] = useState(false);
  return (
    <ScrollView keyboardShouldPersistTaps="always">
      <TextInput
        accessibilityLabel="Kod odbioru"
        onFocus={() => setFocused(true)}
        onBlur={() => {
          setFocused(false);
          setDismissed(false);
        }}
      />
      {focused && !dismissed && (
        <>
          <Text>{instruction}</Text>
          <Pressable
            accessibilityRole="button"
            onPress={() => setDismissed(true)}
          >
            <Text>Ukryj instrukcję</Text>
          </Pressable>
        </>
      )}
      <Text>Odbiór: 6 października, 16:00–18:00.</Text>
    </ScrollView>
  );
}

To komponent wywoływany fokusem, z panelem w przepływie. ScrollView przepuszcza tap przy otwartej klawiaturze. Zamknięcie nie wywołuje blur() ani Keyboard.dismiss(); rzeczywisty responder, utrzymanie fokusu i zewnętrzna klawiatura nie były testowane. Dokumentacja przejrzana; typecheck, build i działanie niewykonane. Callbacks same nie gwarantują zgodności.

WWW / HTML, CSS i JavaScript

Źródłowa demonstracja ma jeden stan widoczności oparty na hover || focused, osobną pamięć świadomego ukrycia oraz obsługę Escape. Pointerleave wspólnego regionu kończy hover, blur wyzwalacza kończy fokus. Nie ma timera zamykającego.

Panel nie zawiera kontrolek, więc nie wymaga przeniesienia fokusu do środka. Menu z kontrolkami wymagałoby także uwzględnienia fokusu potomków. Wariant good ma równoważne wejście przez Tab; w bad identyczne aria-describedby i role="tooltip" nie naprawiają znikania ani braku zamknięcia.

Składnia JavaScript i rzeczywisty przebieg w przeglądarce były sprawdzone w researchu. Ruch przez drag pozostaje ograniczonym dowodem; nie jest pełnym testem fizycznej myszy ani powiększenia.

Jak sprawdzić

  1. Ustal, czy dodatkowa treść wynika z hover/fokusu i kto steruje jej prezentacją. Oceń zasłanianie także przy powiększeniu; nazwa „tooltip” sama nie uzasadnia wyłączenia.
  2. Wywołaj panel osobno fokusem i samym najechaniem. Zapisz rzeczywisty activeElement lub FocusNode, nie tylko klasę CSS.
  3. Zamknij bez zmiany fokusu lub położenia wskaźnika. Panel ma zniknąć, a wyzwalacz pozostać w fokusie/hover. Potwierdź dalsze wpisywanie bez ponownego ustawienia fokusu.
  4. Jeśli hover jest wyzwalaczem, przesuń wskaźnik z wyzwalacza na panel, także wolno i przy powiększeniu. Samo kliknięcie wyzwalacza nie bada hoverable.
  5. Pozostaw fokus/hover i sprawdź timery oraz rzeczywiste przyczyny nieaktualności. Krótka pauza nie wyklucza późniejszego zamknięcia.
  6. Opuść oba obszary lub świadomie zamknij. Wróć i sprawdź ponowne ujawnienie, formularz, cykl, reset i fallback. Dla control potwierdź brak zasłaniania zamiast samego braku przycisku.

Opisane dalej obserwacje obejmują tylko historyczną próbkę. Wyjątku błędu danych i rzeczywistej nieaktualności nie odtwarzano w źródłowej próbce.

Historyczne wyniki z 2026-10-04

Sprawdzenie Faktyczny wynik i zakres
Flutter 3.44.9 / Dart 3.12.2 Analiza, 65 hostowych testów i build iOS PASS; host nie jest testem natywnym.
Końcowy XCTest v3 1 test, 0 błędów, 104,994 s; orkiestracja 112,273 s. 22 stany i 22 drzewa, 44 żądania wejść, 4 PNG.
iOS, ukrycie Good zachował primary focus pola po zamknięciu i pozwolił wpisać P-104 bez ponownego tap. Bad nie miał mechanizmu ukrycia zasłaniającego panelu.
iOS, trwałość i control Panel pozostał przez 6,584 s w good, 6,500 s w bad, 6,433 s w control. Blur do Uwagi ukrywał, powrót do kodu ujawniał. Control nie nakładał się na termin.
WWW, ukrycie Escape przy hover i przy fokusie ukrywał good, bez utraty wyzwalacza; Enter też ukrywał. Bad przy fokusie pozostawał mimo Escape. Control nie reagował na Escape, ale korzystał ze zmierzonego wyjątku niezasłaniania.
WWW, przejście wskaźnika Good/control utrzymały panel przy trigger:hover → tip:hover bez fokusu wyzwalacza; bad zniknął. CUA używało drag: część ruchu buttons=1, odczyt po zwolnieniu buttons=0, pointerenter tip buttons=0; trusted events, bez ustawiania hover przez evaluate.
WWW, trwałość Good utrzymał fokus i panel przez 27,199 s, control 80,672 s. W źródłach JS/Dart próbki nie znaleziono timerów; oba dowody dotyczą tylko tej próbki.
Formularz i nawigacja Wszystkie warianty przyjmowały P-104, potwierdzały lokalny odbiór; cykl usuwał kod/wynik, reset wracał do good, nieznana trasa lub query miały fallback good.
Inne technologie Dokumentacja przejrzana; osobne kompilacje i działanie SwiftUI, Compose i React Native niewykonane.

Środowisko: Xcode 27.0 (27A266a), iPhone 17 / iOS Simulator 26.5, viewport 402×874 logical, DPR 3, PNG 1206×2622. Przeglądarka Codex na macOS: DOM 1280×720, DPR 1 i surowe JPEG 1280×720, dokładna wersja silnika nieustalona. Tryb jasny, bez override viewport/DPR. Dowody WWW obejmują 33 odczyty DOM/stanu/zdarzeń i 12 JPEG. Wybrane kadry pokazują stany; bez filmu i audio, ponieważ zachowanie dokumentuje sekwencja zdarzeń, ramek i odczytów fokusu.

Zachowano dwie nieudane próby natywne. Pierwsza wybrała Uwagi zamiast kodu przez kolejność indeksów AX: 1 test/1 failure, 12,105 s. Druga odczytała fokus kodu, lecz nazwa zamknięcia była scalona z otoczeniem: 1 test/1 failure, 27,533 s. Poprawiono wybór według rzeczywistej ramki i granicę Semantics; końcowy PASS nie usuwa wcześniejszych wyników. Odmowa cache SDK i niekompletny pierwszy callback WWW są zachowaną historią narzędzi, nie wynikami kryterium.

Weryfikacja i ograniczenia

Obraz pozwala zobaczyć nakładanie i tekst, ale nie dowodzi braku timera, utrzymania fokusu ani przejścia wskaźnika. Drzewo może zawierać tekst wizualnie przykryty, a ramka nie dowodzi sama nieprzezroczystości warstwy. Tutaj zestawiono źródło, rzeczywiste obrazy i odczyty. Trusted events i :hover opisują przeglądarkę, bez potwierdzenia sprzętowej myszy.

Observer odczytuje istniejące FocusNode i RenderBox, nie ustawia fokusu ani panelu i nie eksportuje oczekiwanego werdyktu. Callback WWW tylko czyta stan. Checker zna warianty: jego PASS potwierdza przebieg i integralność próbki, bez zaślepionej oceny dostępności lub wyniku ACT. Kadry obejrzało AI, bez przeglądu człowieka.

Jak sprawdza Clearship

Detektor focus-content-1 na Androidzie zbiera kandydatów treści pojawiającej się po fokusie klawiatury. Wraca na wyzwalacz, czeka 3 sekundy i wysyła Escape. Szuka zniknięcia przy zachowanym fokusie albo panelu zasłaniającego wcześniejszą treść, którego Escape nie ukrywa bez utraty fokusu. Nie bada hover, treści WWW ani iOS; przejście klawiaturowe iOS jest niedostępne.

Analizator porównuje nową treść z drzewem ekranu startowego, żeby przewinięcie istniejącego elementu nie udawało pojawienia się panelu. Zasłanianie przybliża ramkami: minimum 20% mniejszej ramki, bez oceny zasłaniania przy przesunięciu wcześniejszej treści ponad 8 px. To parametry metody, a nie progi WCAG. Potencjalny błąd danych, brak ponownego wyzwolenia, zmieniony fokus, pominięte cele lub niepełny kanał kierują ocenę do człowieka. Trzy sekundy nie wykluczają późniejszego timera; wyjątki platformy i powiększenie wymagają osobnej oceny.

Pomiar Androida z 2026-10-08 pozostał poniżej progu: 3 z 6 usterek, 0 fałszywych alarmów na 80 poprawnych ekranach zestawu kontrolnego, próba 1/3. W zebranym pakiecie Fluttera nie pojawia się treść zależna od klawiaturowego trybu wskazania, więc ekran trafia do człowieka. iOS pozostaje bez pomiaru kontrolnego. Kandydat lub brak zgłoszenia nie potwierdza trzech warunków całego kryterium; potrzebna jest ocena człowieka. Wyniki researchowej demonstracji opisane wyżej są osobnym materiałem.

Powiązane kryteria