Content Description est une propriété d'accessibilité qui transmet une description textuelle du contenu non textuel aux technologies d'assistance. Sur iOS, c'est l'attribut accessibilityHint pour UIView, sur Android — contentDescription dans le balisage XML. Selon W3C WCAG 2.2, 2023, l'absence d'alternatives textuelles pour le contenu non textuel est l'une des violations d'accessibilité les plus courantes dans les applications mobiles. Des descriptions correctement remplies rendent l'application accessible aux personnes malvoyantes qui utilisent VoiceOver et TalkBack.
Points clés
Content Description est une propriété de chaîne d'un élément d'interface qui fournit une représentation textuelle du contenu visuel aux technologies d'assistance. Un lecteur d'écran (VoiceOver sur iOS, TalkBack sur Android) lit la description à haute voix au lieu d'essayer de reconnaître l'élément visuellement. Les descriptions s'appliquent aux images sans couche de texte, aux icônes, aux graphiques, aux contrôles personnalisés et à tout élément non textuel.
Selon Google Material Design, 2024, les éléments sans contentDescription violent WCAG 1.1.1 (Non-text Content). Les vérifications d'Accessibility Scanner montrent que jusqu'à 40 % des icônes dans les applications shopping n'ont pas de description. Un utilisateur de VoiceOver entend « image » ou « bouton » sans précision — une telle interface devient inutilisable pour la navigation.
Content Description ne remplace pas le texte visible d'un élément. Si un bouton contient le libellé « Envoyer », il n'est pas nécessaire de définir une description supplémentaire — le lecteur d'écran lira le texte. Pour les images, les icônes et les champs de saisie, la description est obligatoire.
Les outils Accessibility Scanner (Android) et Xcode Accessibility Inspector (iOS) vérifient automatiquement la présence de descriptions. Il est recommandé d'effectuer ces vérifications sur chaque écran avant la publication.
Un utilisateur malvoyant dépend de VoiceOver pour comprendre l'interface. Si une icône de panier n'a pas de description, il entend seulement « bouton ». Pour savoir ce que fait le bouton, il doit appuyer à l'aveugle — risquant une action irréversible. Une description comme « Supprimer l'article du panier » résout ce problème en une seconde.
Un utilisateur avec des limitations temporaires (soleil éclatant à l'extérieur, écran cassé) utilise aussi VoiceOver. Selon Apple Accessibility Report, 2023, environ 20 % des utilisateurs de VoiceOver n'ont pas de déficiences visuelles permanentes — ils activent la fonction situationnellement.
Le critère WCAG 1.1.1 (Niveau A) exige que tout contenu non textuel ait une alternative textuelle. Exception : le contenu décoratif, utilisé uniquement pour la présentation visuelle ou qui ne transmet pas d'informations. Le test de décorativité : si vous supprimez l'élément, le sens de la page change-t-il ? Si non — il peut être masqué au lecteur d'écran.
Accessibility Label (accessibilityLabel sur iOS) est le nom de l'élément que le lecteur d'écran prononce lors de la prise de focus. Content Description (accessibilityHint sur iOS) est une clarification supplémentaire annoncée après le nom qui indique le résultat d'une action.
La différence est claire avec l'exemple d'un bouton « Panier ». Label : « Panier ». Description : « Ouvrira l'écran de paiement ». VoiceOver dit : « Panier. Ouvrira l'écran de paiement ». Si seul le Label est défini, l'utilisateur ne saura pas ce qui se passe après avoir tapé.
| Propriété | iOS | Android | Objectif |
|---|---|---|---|
| Label | accessibilityLabel | contentDescription | Nom de l'élément (bouton, champ, image) |
| Description | accessibilityHint | contentDescription (étendue) | Clarification de l'action ou du sens |
| Trait | accessibilityTraits | role / className | Rôle de l'élément (bouton, en-tête) |
Règle : Label répond à « Qu'est-ce que c'est ? », Description répond à « Que va-t-il se passer ? ». Sur Android, contentDescription peut jouer les deux rôles, mais en pratique il est préférable de les séparer : utiliser la concaténation « [nom], [explication] ».
Pour les gestes complexes (balayer pour supprimer, appui long pour le menu contextuel), accessibilityHint est obligatoire. Un utilisateur de VoiceOver ne connaît pas les gestes cachés s'ils ne sont pas décrits. Indiquez : « Balayez vers la gauche pour supprimer » dans le hint de l'élément.
Sur la plateforme iOS, accessibilityHint est défini via la propriété éponyme de UIView ou NSObject. La valeur est une chaîne de jusqu'à 80 caractères. VoiceOver lit le hint après le label lorsque le mode de descriptions détaillées est activé (dans les réglages VoiceOver — « Verbosity »).
Exemple de définition d'un hint pour un bouton personnalisé :
import UIKit
class CustomButton: UIButton {
override func awakeFromNib() {
super.awakeFromNib()
self.accessibilityLabel = "Ajouter aux favoris"
self.accessibilityHint = "Enregistrera l'article dans la liste des favoris"
}
}
Pour UIImageView sans contenu textuel, il est obligatoire de définir isAccessibilityElement = true et accessibilityHint :
let imageView = UIImageView(image: UIImage(named: "chart-sales"))
imageView.isAccessibilityElement = true
imageView.accessibilityHint = "Graphique des ventes du dernier trimestre"
VoiceOver lit : « Graphique des ventes du dernier trimestre ». Si le hint est vide — seulement « image ». Apple HIG, 2024 recommande de ne pas utiliser de verbes comme « appuyez » ou « tapez » dans les hints — VoiceOver ajoute automatiquement une instruction gestuelle.
Dans SwiftUI, le hint est défini via un modificateur en chaîne :
Image(systemName: "trash")
.accessibilityLabel("Supprimer")
.accessibilityHint("Supprimera définitivement l'élément sélectionné")
SwiftUI combine automatiquement les modificateurs pour les vues composites. Si une Image se trouve à l'intérieur d'un Button, SwiftUI utilise le libellé du bouton comme accessibilityLabel principal.
Sur Android, contentDescription est défini soit dans le balisage XML, soit par programme via setContentDescription(). TalkBack annonce la description lorsque l'élément reçoit le focus.
Exemple en XML :
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_search"
android:contentDescription="Rechercher des produits" />
Définition programmatique pour les éléments dynamiques :
binding.iconSearch.contentDescription =
"Rechercher. Ouvrira l'écran de recherche avec des filtres"
Pour les images décoratives (séparateurs, fonds, icônes décoratives), définissez contentDescription = "@null" ou setContentDescription(null) — TalkBack ignorera ces éléments. En XML : android:contentDescription="@null". Une chaîne vide "" ne fonctionne pas — TalkBack annoncera quand même « image ».
Pour ImageButton, définissez toujours contentDescription — TalkBack ne voit pas le texte sur les images. Pour CheckBox, la description doit changer dynamiquement : « Sélectionné » / « Non sélectionné » au lieu d'une description statique. Utilisez setContentDescription dans l'écouteur d'état.
Informativité — la description doit transmettre le sens, pas l'apparence. Pas « Icône bleue avec une coche », mais « Article ajouté au panier ». Un lecteur d'écran ne s'intéresse pas aux couleurs — il s'intéresse au résultat.
Concision — la longueur optimale est de 2 à 4 mots (jusqu'à 80 caractères). Les descriptions longues ralentissent la navigation : VoiceOver lit séquentiellement, chaque mot représente une seconde du temps de l'utilisateur. Selon Apple WWDC 2023, « Accessibility by Design », une phrase qui prend plus de 5 secondes à lire interrompt le flux cognitif.
Unicité — il ne doit pas y avoir deux éléments sur le même écran avec la même description. L'utilisateur ne pourra pas distinguer quel résultat provoquera le focus sur le premier élément par rapport au second. S'il y a plusieurs boutons « Acheter », ajoutez un identifiant : « Acheter iPhone 15 », « Acheter iPhone 15 Pro ».
Localisation — Content Description doit être traduit dans toutes les langues prises en charge par l'application. Une erreur de localisation dans les descriptions est l'une des causes courantes d'échec d'une Accessibility Review dans l'App Store.
Une étude du Nielsen Norman Group, 2024 a montré que la longueur optimale de description pour les lecteurs d'écran est de 3 à 5 mots (jusqu'à 50 caractères). Les descriptions plus longues réduisent la vitesse de navigation de 30 %, car l'utilisateur doit attendre la fin de l'annonce avant l'étape suivante.
Redondance — la description duplique le texte visible. Si un bouton contient le texte « Envoyer », ne définissez pas accessibilityHint = « Bouton envoyer ». VoiceOver lira le texte automatiquement, et le hint ajoutera un bruit inutile.
Confusion avec Label — utiliser contentDescription au lieu d'un label pour les boutons textuels. Sur iOS, accessibilityLabel doit correspondre au texte du bouton (ou être vide si le texte est déjà visible), et le hint doit seulement clarifier l'action. Selon Google Testing Blog, 2024, 23 % des applications examinées dans le Play Store ont des descriptions en double.
Ignorer la dynamique — la description n'est pas mise à jour lors du changement d'état. Par exemple, la description d'un interrupteur « Wi-Fi » reste « Activer Wi-Fi » même après avoir été allumé. Approche correcte : changer dynamiquement la description en « Désactiver Wi-Fi » en observant l'état.
Après une mise à jour de design (changement d'icônes, réorganisation d'éléments), Content Description est souvent perdu. Raison : le designer remplace une image et le développeur ne vérifie pas les propriétés d'accessibilité du nouvel asset. Solution : faire de la vérification d'accessibilité une étape obligatoire dans la revue de code — ajouter un élément de checklist : « Content Description a-t-il été mis à jour ? »
func testContentDescriptionExists() {
let app = XCUIApplication()
app.launch()
let image = app.images["chart-sales"]
XCTAssertNotNil(image.label)
XCTAssertGreaterThan(image.label.count, 0)
}
Questions fréquentes
VoiceOver ou TalkBack annoncera simplement « image » ou « bouton » sans indiquer son objectif. Cela viole WCAG 1.1.1 et rend l'application inaccessible aux personnes malvoyantes.
Non. Si le bouton a un libellé textuel, VoiceOver le lit automatiquement. Une description (accessibilityHint) peut être ajoutée pour clarifier le résultat de l'appui, mais un Label n'est pas requis.
Sur iOS, définissez isAccessibilityElement = false. Sur Android, définissez contentDescription = "@null". Le lecteur d'écran ignorera complètement ces éléments sans émettre de son.
Sur iOS, utilisez NSLocalizedString pour accessibilityHint, sur Android — les ressources chaîne via @string/. La traduction des descriptions est obligatoire pour toutes les langues prises en charge.
Ajoutez des tests UI qui vérifient la présence de descriptions pour tous les ImageView. Sur iOS — XCUIApplication, sur Android — AccessibilityCheckRule d'Espresso. Accessibility Scanner peut être exécuté en CI via la ligne de commande.
Résumé
Nous développerons une application mobile clé en main
IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.
Lisez aussi