Focus Order is de volgorde waarin interface-elementen focus krijgen bij navigatie met het toetsenbord, Switch Control, VoiceOver of TalkBack. In mobiele apps bepaalt de focusvolgorde hoe de gebruiker tussen controls beweegt met gebaren of knoppen. Volgens W3C WCAG 2.2, Success Criterion 2.4.3, 2023 moet focus in een logische volgorde verlopen die de betekenis van de content behoudt. Schending van dit principe is een van de meest voorkomende oorzaken dat een toegankelijkheidsaudit mislukt.
Belangrijkste punten
Focus Order is de volgorde waarin de gebruiker tussen interactieve elementen beweegt met alternatieve invoermethoden: toetsenbord (Tab), Switch Control (stap voor stap), VoiceOver (gebaar naar rechts/links) of TalkBack. In tegenstelling tot een muis of touchscreen, waarbij de gebruiker een element direct selecteert, is focussnavigatie lineair — elke stap verplaatst de focus naar het volgende element.
Volgens Apple HIG, 2024 gebruikt VoiceOver de volgorde van elementen in de accessibility-boom, die wordt opgebouwd op basis van visuele plaatsing: linker bovenhoek → rechter benedenhoek. Als een scherm een complexe lay-out bevat (kolommen, Grid, ZStack), kan de boom niet overeenkomen met de visuele volgorde.
Het principe van WCAG 2.4.3: „Als een webpagina opeenvolgend per sectie kan worden doorlopen en de focusvolgorde invloed heeft op de betekenis, dan moet de focus een volgorde volgen die de betekenis en de bedienbaarheid behoudt”. Uitzondering: dynamische content waarbij de focus mag springen om aandacht te trekken (waarschuwingen, modale vensters).
Een Switch Control-gebruiker (mensen met motorische beperkingen) beweegt automatisch tussen elementen — cyclus na cyclus. Als de volgorde is verbroken, besteedt de gebruiker 3 keer zoveel tijd aan het invullen van een formulier. Volgens Deque University, 2024 verkort een correcte Focus Order de tijd voor het invullen van formulieren met 60% voor gebruikers van ondersteunende technologie.
Bijzondere aandacht gaat uit naar modale vensters. Na het openen van een modaal venster moet de focus onmiddellijk verplaatst worden naar het eerste interactieve element in het modaal (meestal de knop „Sluiten” of „Bevestigen”). Na het sluiten moet de focus terugkeren naar het element dat het modale venster heeft geopend. Dit is een vereiste van WCAG 2.4.3 en tegelijkertijd een veelvoorkomende fout.
In iOS bouwt VoiceOver de volgorde automatisch op basis van geometrie: elementen worden gesorteerd op Y, daarna op X. Voor schermen met een complexe structuur kan deze volgorde onjuist zijn — de ontwikkelaar moet ingrijpen.
De belangrijkste instrumenten:
Voorbeeld van het instellen van een aangepaste volgorde voor een productkaart:
class ProductCardView: UIView {
let titleLabel = UILabel()
let priceLabel = UILabel()
let buyButton = UIButton()
override var accessibilityElements: [Any]? {
get {
return [titleLabel!, priceLabel!, buyButton!]
}
set {}
}
}
Voor het programmatisch verplaatsen van de focus na een actie:
UIAccessibility.post(
notification: .layoutChanged,
argument: newlyAddedItem
)
De eigenschap shouldGroupAccessibilityElement is nuttig voor kaarten in collecties. Als u true instelt op de bovenliggende kaart, ervaart VoiceOver de hele kaart als één element. De gebruiker kan dubbeltikken om de hele kaart te activeren of de rotor instellen voor navigatie erin. Aanbevolen voor UICollectionViewCell en UITableViewCell.
In Android gebruikt TalkBack ook de geometrische volgorde, maar de prioriteit gaat naar de expliciete nextFocus*-attributen. Deze attributen worden ingesteld in XML of programmatisch:
| Attribuut | Functie | Voorbeeld |
|---|---|---|
| nextFocusDown | Element bij navigatie naar beneden | @+id/field_email |
| nextFocusUp | Element bij navigatie naar boven | @+id/field_name |
| nextFocusLeft | Element aan de linkerkant | @+id/btn_back |
| nextFocusRight | Element aan de rechterkant | @+id/btn_next |
Voorbeeld voor een registratieformulier:
<EditText
android:id="@+id/field_email"
android:nextFocusDown="@+id/field_password" />
<EditText
android:id="@+id/field_password"
android:nextFocusDown="@+id/btn_submit" />
Voor RecyclerView is de focusvolgorde dynamisch — deze wordt bepaald door de adapter. Als cellen een complexe structuur hebben, stelt u descendantFocusability = "beforeDescendants" in en bepaalt u de volgorde in het knooppunt van het lijstelement. Voor Jetpack Compose wordt de focusvolgorde ingesteld via Modifier.focusOrder() en FocusOrder. Prioriteit: previous (onderliggend), next (volgende), custom key.
Als een element te klein is voor focus (kleiner dan 44pt), vergroot u de hit area via TouchDelegate in iOS of minWidth/minHeight in Android. Volgens Google Material Design, 2024 is het minimale aanraakoppervlak 48×48dp. VoiceOver en TalkBack focussen op de bounding box van het element. Elementen kleiner dan 30pt kunnen ontoegankelijk zijn voor gebarenfocus — de gebruiker kan er fysiek niet met de vinger bij.
Springende focus — wanneer na een actie (bijvoorbeeld het verwijderen van een element) de focus naar het begin van de lijst of naar de systeemknop „Terug” springt. De VoiceOver-gebruiker verliest de context. Oplossing: verplaats de focus programmatisch naar het element dat het dichtst bij het verwijderde element ligt.
Onzichtbare focus — een element krijgt focus, maar er is geen visuele indicator (toetsenbordgebruikers zien niet waar ze zijn). In iOS controleert u UIAccessibility.isVoiceOverRunning voor aangepaste indicatoren. Volgens Deque University, 2024 is onzichtbare focus de tweede meest voorkomende oorzaak van het falen van een toegankelijkheidsaudit.
Modale vensters — de focus blijft op de achtergrondcontent na het openen van een modaal venster. In iOS vangt de modale view automatisch de focus af als modalPresentationStyle = .pageSheet is ingesteld. In Android gebruikt u setFocusable(true) op de container van het dialoogvenster.
Het omgekeerde probleem: de focus blijft steken in het modale venster en kan er niet uit (behalve door te sluiten). Dit is alleen toegestaan voor modale vensters — de gebruiker moet het venster bewust sluiten. Voor gewone schermen is een focus trap een kritieke fout. Oplossing: zorg ervoor dat het laatste element van het modale venster (de knop „Sluiten”) de focus teruggeeft.
Voor aangepaste schermen (kaarten, canvassen, games) is de automatische geometrische volgorde niet toepasbaar. De ontwikkelaar moet de accessibility-boom handmatig opbouwen. In iOS wordt hiervoor de methode UIAccessibilityContainer overschreven.
Voorbeeld voor een aangepast canvas:
class CanvasView: UIView {
var shapes: [ShapeView] = []
override var accessibilityElements: [Any]? {
get {
// We sorteren de figuren op Z-index, niet op geometrie
return shapes.sorted { $0.zIndex < $1.zIndex }
}
set {}
}
}
In Android overschrijft u voor een aangepaste View onInitializeAccessibilityNodeInfo:
override fun onInitializeAccessibilityNodeInfo(
info: AccessibilityNodeInfo
) {
super.onInitializeAccessibilityNodeInfo(info)
info.addChild(firstElement)
info.addChild(secondElement)
info.isFocusable = true
}
Voor dynamische lijsten (chat, nieuwsfeed) roept u na het toevoegen van een element de verplaatsing van de focus naar het eerste nieuwe element aan. In iOS: UIAccessibility.post(notification: .layoutChanged, argument: newMessage). In Android: sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED).
iOS bepaalt automatisch het focusgebied op basis van het frame van het element. Als een element een transformatie heeft (transform, rotation), kan VoiceOver op het verkeerde gebied focussen. Stel accessibilityFrame expliciet in in schermcoördinaten: element.accessibilityFrame = UIAccessibility.convertToScreenCoordinates(element.bounds, in: element). Dit garandeert dat VoiceOver het juiste gebied markeert.
Voor geanimeerde schermen (UIKit Dynamics, Lottie, SpriteKit) is programmatische focus bijzonder belangrijk. VoiceOver kan geen accessibility-boom opbouwen voor dynamisch bewegende elementen. Stel isAccessibilityElement = false in op de animatiecontainers en alleen true op de interactieve elementen erin.
Handmatig testen: zet VoiceOver (iOS) of TalkBack (Android) aan en veeg met een gebaar naar rechts door de hele volgorde. De focus moet de visuele volgorde volgen — van links naar rechts, van boven naar beneden. Elk interactief element moet precies één keer focus krijgen.
Geautomatiseerd testen is moeilijk, maar mogelijk:
func testKeyboardFocusOrder() {
let app = XCUIApplication()
app.launch()
app.textFields["Email"].tap()
// Tab — alleen met een hardwaretoetsenbord
}
Voor Android gebruikt u het Accessibility Testing Framework:
@Test
fun testFocusOrder() {
onView(withId(R.id.fieldEmail))
.check(matches(isFocusable()))
onView(withId(R.id.fieldEmail))
.perform(focus())
onView(withId(R.id.fieldPassword))
.check(matches(isFocused()))
}
De meest betrouwbare methode is een UI-test van het scenario: vul het formulier stap voor stap in (Email → Wachtwoord → Verzenden) en controleer dat elke stap succesvol is. Als de focusvolgorde is verbroken, faalt het scenario bij het proberen te interacteren met een element buiten de focus.
Het hulpmiddel Accessibility Inspector in Xcode toont de volledige accessibility-boom. U kunt in de VoiceOver-volgorde door elementen lopen en het exacte focustraject zien. Gebruik het tabblad „Audit” voor automatische detectie van Focus Order-schendingen.
Veelgestelde vragen
WCAG 2.4.3 (Focus Order) is een succescriterium van niveau A. Het vereist dat de focusvolgorde de betekenis van de content behoudt bij opeenvolgende navigatie. Een schending wordt als kritiek beschouwd en blokkeert de certificering.
Verborgen elementen moeten in iOS isAccessibilityElement = false hebben of visibility = gone/invisible in Android. Wanneer ze verschijnen, verplaatst u de focus programmatisch via UIAccessibility.post(notification: .layoutChanged).
iOS beheert via accessibilityElements en shouldGroupAccessibilityElement, Android via de nextFocus*-attributen en AccessibilityNodeInfo. Het principe is hetzelfde: standaard een geometrische volgorde met de mogelijkheid om deze te overschrijven.
Stel descendantFocusability = "beforeDescendants" in op het root-element en configureer de volgorde in de adapter via onInitializeAccessibilityNodeInfo voor elke cel.
Sluit een hardwaretoetsenbord aan via Bluetooth of USB. In iOS drukt u op Tab om de focus te verplaatsen. In Android schakelt u TalkBack in en gebruikt u de Tab- en pijltjestoetsen.
Samenvatting
We ontwikkelen een mobiele applicatie turnkey
IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.
Lees ook