SKILL-11 — Consultation¶
Taille des zones de touche, contrôle du temps et erreurs irréversibles
Critères couverts¶
| Critère RAAM | Intitulé | Niveau | WCAG |
|---|---|---|---|
| 11.1 | L'utilisateur contrôle les limites de temps et éléments en mouvement | [A] | WCAG 2.2.1, 2.2.2 |
| 11.5 | Les zones de touche ont une dimension suffisante | [AA] | WCAG 2.5.5 |
| 11.6 | Les actions importantes ont une confirmation ou récupération | [AA] | WCAG 3.3.4 |
Pourquoi c'est important¶
Zones de touche minimales
C'est l'une des règles les plus violées. iOS recommande 44x44 pt et Android 48x48 dp comme zone minimale de tap. Une icône peut être petite (ex: 20x20) tant que la zone interactive invisible autour est grande.
Ces règles impactent directement la motricité fine (cibler un bouton) et le stress lié au temps. Un utilisateur doit avoir le temps de corriger une action ou comprendre un message.
Patterns¶
1. Zone de touche [AA]¶
Button(action: { print("Action") }) {
Image(systemName: "star")
.resizable()
.frame(width: 20, height: 20) // Visuel petit
}
.frame(minWidth: 44, minHeight: 44) // Zone cliquable large
.contentShape(Rectangle()) // Indispensable pour rendre le padding cliquable
.accessibilityLabel("Mettre en favori")
2. Timeout et Expiration [A]¶
.alert(isPresented: $isTimeoutWarningVisible) {
Alert(
title: Text("Expiration de session imminente"),
message: Text("Votre session expirera dans \(timeRemaining) secondes."),
primaryButton: .default(Text("Prolonger la session")) { resetSession() },
secondaryButton: .cancel(Text("Me déconnecter"))
)
}
AlertDialog(
onDismissRequest = { },
title = { Text("Expiration de session imminente", modifier = Modifier.semantics { liveRegion = LiveRegionMode.Assertive }) },
text = { Text("Voulez-vous la prolonger ?") },
confirmButton = { TextButton(onClick = { }) { Text("Prolonger") } },
dismissButton = { TextButton(onClick = { }) { Text("Déconnecter") } }
)
3. Erreurs Récupérables [AA]¶
Button(role: .destructive) {
isDeleteConfirmationPresented = true
} label: { Text("Supprimer le compte") }
.confirmationDialog("Cette action est irréversible.", isPresented: $isDeleteConfirmationPresented) {
Button("Supprimer", role: .destructive) { deleteAccount() }
Button("Annuler", role: .cancel) { }
}
AlertDialog(
onDismissRequest = { showDeleteConfirmation = false },
title = { Text("Supprimer définitivement ?") },
text = { Text("Cette action est irréversible.") },
confirmButton = { Button(onClick = { /* Delete */ }) { Text("Oui, supprimer") } },
dismissButton = { TextButton(onClick = { showDeleteConfirmation = false }) { Text("Annuler") } }
)
4. Données conservées après erreur [AA]¶
Règle
Si un utilisateur se trompe dans un champ email, n'effacez pas tous les autres champs du formulaire au moment de l'affichage de l'erreur ! Conservez sa saisie.
5. Mouvements de glissement [2.2 · AA]¶
Hors RAAM 1.1, hors scoring
2.5.7 : toute action par glissement (réordonner, déplacer) doit avoir une alternative à un seul appui : accessibilityAction(named:) + contextMenu (iOS), boutons visibles + customActions (Compose). Détails : Extensions WCAG 2.2.
Checklist [A] / [AA]¶
- Boutons tactiles font au moins 44x44 pt (iOS) ou 48x48 dp (Android).
- Les sessions expirantes alertent l'utilisateur et peuvent être prolongées.
- Les suppressions ou paiements exigent une confirmation.
- Les champs ne sont jamais vidés suite à une erreur de validation.