Reading Order Contract
Status: ready
Intent
The order VoiceOver, Switch Control and the keyboard follow matches the user's task.
Problem
The visual order is clear, but VoiceOver follows the implementation tree. The button is read before the error it fixes. The price comes before the product name. A sheet opens and focus stays behind it.
Solution
Verdict: write the expected order for every critical screen in design review. Get it from code structure first, explicit order second.
Why: a written order gives design, development and QA the same target. Without it, the order is whatever the layout code happens to produce.
Checkout, error state:
1. Screen title
2. Error summary
3. First invalid field
4. Primary action
5. Support link
Implementation
SwiftUI, the code is already in task order. No priorities needed:
VStack(alignment: .leading) {
Text("Payment").font(.title.bold())
.accessibilityAddTraits(.isHeader)
ErrorSummary(errors)
CardForm()
Button("Pay") { pay() }
}
SwiftUI, when the layout forces a different visual order. Higher priority is read first, within one container:
VStack {
Text("Payment failed").accessibilitySortPriority(3)
TextField("Card number", text: $card).accessibilitySortPriority(2)
Button("Try again") { pay() }.accessibilitySortPriority(1)
}
.accessibilityElement(children: .contain)
If every element needs a priority, the view structure needs fixing, not more priorities.
UIKit, custom container:
view.accessibilityElements = [
titleLabel,
errorLabel,
cardNumberField,
payButton,
supportButton
]
Update the array when elements appear or disappear. An element missing from it can't be reached.
Check
Profile: VoiceOver
Task: recover from a failed payment
Expected: the order matches the written contract
the error comes before "Try again"
nothing behind the sheet is reachable
Profile: VoiceOver, Arabic locale
Task: the same
Expected: the same task order, with the visual layout mirrored
Profile: Switch Control
Task: scan the form
Expected: the same order as VoiceOver
Pitfalls
- An order that contradicts what the user sees.
- Priorities as a patch for a chaotic layout.
- Only the happy path written down. Error states and sheets need their own order.
- Assuming a
ZStackreads front to back.
WCAG mapping
1.3.2 Meaningful Sequence: the order preserves meaning.2.4.3 Focus Order: focus order supports the task.3.3.1 Error Identification: the error comes where the user can act on it.