Accessibility Label est le nom d'un élément d'interface que VoiceOver (iOS) ou TalkBack (Android) énonce lors de la mise au point. Sous iOS, la propriété est appelée accessibilityLabel, sous Android — contentDescription pour les éléments qui ne contiennent pas de texte. Selon Apple Developer Documentation, 2024, le libellé est le fondement de l'accessibilité : sans lui, l'utilisateur ne peut pas identifier l'élément. Le libellé doit être unique dans l'écran et refléter l'essence de l'élément dans un langage clair.
Points essentiels
Accessibility Label est une propriété de chaîne qui définit le nom d'un élément pour les technologies d'assistance. Lorsque l'utilisateur fait glisser son doigt sur l'écran avec VoiceOver activé, le lecteur d'écran lit le libellé de l'élément focalisé. Sans libellé, l'utilisateur entend seulement le type d'élément : « bouton », « image » — sans indication de son objectif.
Selon Google I/O 2024, « Accessibility Testing », 35 % des violations critiques d'accessibilité dans les applications de boutique sont liées à l'absence ou à l'incorrection des libellés. Accessibility Scanner sur Android détecte l'absence de libellé comme une erreur de gravité maximale.
Une limitation fondamentale : le libellé ne doit pas contenir le type d'élément. VoiceOver et TalkBack ajoutent automatiquement le rôle (bouton, en-tête, lien) à l'annonce. Si le libellé contient « Bouton d'envoi », l'utilisateur entendra : « Bouton d'envoi, bouton » — duplication.
WCAG 4.1.2 (niveau A) exige que chaque élément d'interface utilisateur ait un nom, un rôle et une valeur déterminables par programmation. Accessibility Label fournit le nom. Si le libellé est absent, le critère est considéré comme violé et l'application ne réussit pas la certification de base.
Sous iOS, accessibilityLabel est hérité par tous les UIView du protocole UIAccessibility. Si un élément contient du texte (UIButton avec titre, UILabel avec texte), le libellé est automatiquement défini sur ce texte. Pour UIImageView, les contrôles personnalisés et les conteneurs, le libellé doit être défini manuellement.
Exemple pour une cellule de tableau personnalisée :
class CustomTableViewCell: UITableViewCell {
let titleLabel = UILabel()
let priceLabel = UILabel()
override func awakeFromNib() {
super.awakeFromNib()
self.isAccessibilityElement = true
self.accessibilityLabel =
"\(titleLabel.text ?? "") - \(priceLabel.text ?? "")"
}
}
Pour les UIView personnalisées, vous pouvez remplacer le getter accessibilityLabel :
class RatingView: UIView {
var rating: Int = 5
override var accessibilityLabel: String? {
get { return "Évaluation : \(rating) sur 5" }
set {}
}
}
Apple HIG, 2024 conseille : si un élément se compose de plusieurs sous-éléments (par exemple, une carte produit avec nom et prix), combinez-les en un seul élément d'accessibilité avec un libellé composite. Définissez isAccessibilityElement = true sur le parent et false sur les enfants.
Si UILabel utilise NSAttributedString, accessibilityLabel est par défaut égal à .string (texte brut). Si vous devez transmettre une valeur sémantiquement différente (par exemple, une icône de symbole se lit comme « Étoile » au lieu du caractère ★), définissez explicitement accessibilityLabel. VoiceOver ne lit pas les caractères Unicode de manière significative.
Sous Android, contentDescription sert de libellé pour ImageView, ImageButton et les vues personnalisées. Pour TextView et Button avec texte intégré, il n'est pas nécessaire de définir contentDescription — TalkBack lit le texte automatiquement.
Définition par programmation via Kotlin :
binding.iconStar.contentDescription = "Produit en favoris"
// Pour une vue personnalisée avec plusieurs éléments
binding.customCard.setContentDescription(
"\(title) pour \(price)")
En XML pour les éléments décoratifs :
<ImageView
android:contentDescription="@null"
android:src="@drawable/divider"
android:importantForAccessibility="no" />
La propriété importantForAccessibility = « no » exclut complètement l'élément de l'arbre d'accessibilité. Sous iOS, l'équivalent est isAccessibilityElement = false.
Dans Jetpack Compose, le libellé est défini via le modificateur semantics :
Image(
painter = painterResource(R.drawable.ic_search),
contentDescription = "Rechercher des produits",
modifier = Modifier.semantics {
contentDescription = "Rechercher des produits"
}
)
Dans Compose, contentDescription est un paramètre obligatoire pour Image — sans lui, le code ne se compile pas (avertissement). Cela améliore de force l'accessibilité via la conception de l'API.
Accessibility Label répond à la question « Qu'est-ce que cet élément ? ». Hint (accessibilityHint sous iOS, texte supplémentaire dans contentDescription sous Android) — « Que se passera-t-il lors de l'interaction ? ». VoiceOver les annonce séquentiellement : d'abord Label, puis Hint.
Exemple pour un bouton de suppression :
Selon Deque University, 2024, la séparation appropriée de Label et Hint améliore le taux d'achèvement des tâches pour les utilisateurs de VoiceOver de 28 %. Les utilisateurs souffrant de troubles cognitifs dépendent particulièrement de Hint : lorsqu'ils ne sont pas sûrs d'appuyer sur « Supprimer » sans explication, 40 % refusent l'action.
Une erreur fréquente : écrire « Bouton de suppression » dans Label au lieu de « Supprimer ». Le type d'élément (Bouton) est ajouté automatiquement par VoiceOver via un trait. En résultat, l'utilisateur entend : « Bouton de suppression, bouton » — duplication. Label correct : « Supprimer », Hint : « Supprime la photo sélectionnée ».
La localisation des libellés est obligatoire — elle passe par des mécanismes standard : NSLocalizedString sous iOS, ressources de chaîne @string/ sous Android. Ne définissez jamais un libellé par concaténation en anglais sans localisation.
Règles pour un bon libellé, basées sur W3C WCAG 2.2 :
Utilisez un glossaire unique pour les libellés dans toute l'application. Si un écran indique « Favoris » et un autre « Signets », l'utilisateur est désorienté. Créez un tableau de terminologie d'accessibilité — coordonnez avec les concepteurs et les localisateurs.
Pour les champs de saisie (UITextField, EditText), le libellé doit correspondre au placeholder ou au libellé du champ. Cependant, le placeholder disparaît souvent après la saisie du texte. Utilisez accessibilityLabel pour le nom permanent et accessibilityValue pour le contenu actuel du champ — c'est la norme WCAG 4.1.2. Solution : définissez accessibilityLabel statiquement (égal au libellé du champ) et accessibilityValue dynamiquement (égal au texte saisi). Sous iOS, c'est automatique, mais pour les champs personnalisés — manuellement en remplaçant accessibilityValue. Vérifiez que VoiceOver lit : « E-mail, exemple@domaine.com, champ de texte » au lieu de « , champ de texte ».
Les tests automatisés sont la seule façon de garantir la correction des libellés sur tous les écrans. iOS fournit XCUIApplication avec accès à .label, Android — AccessibilityCheckRule et setContentDescription.
Exemple de test pour iOS :
func testLabelsAreUnique() {
let app = XCUIApplication()
app.launch()
let allButtons = app.buttons.allElementsBoundByIndex
let labels = allButtons.compactMap { $0.label }
let uniqueLabels = Set(labels)
XCTAssertEqual(labels.count, uniqueLabels.count,
"Libellés en double trouvés")
}
Exemple pour Android avec Espresso :
@Test
fun testButtonHasAccessibilityLabel() {
onView(withId(R.id.btnSubmit))
.check(matches(
withContentDescription(containsString("Envoyer"))
))
}
Tests manuels : activez VoiceOver (iOS) ou TalkBack (Android) et balayez vers la droite sur tous les éléments de l'écran. Chaque élément doit recevoir une annonce significative. Si vous n'entendez que « bouton » ou « image » — le libellé est absent.
Après avoir configuré le libellé, les utilisateurs de VoiceOver peuvent utiliser le rotor pour une navigation rapide : modes « Boutons », « En-têtes », « Liens » et autres. Si le libellé est correctement défini, VoiceOver inclut l'élément dans le mode de rotor correspondant. Vérifiez que tous les boutons sont visibles en mode « Boutons », tous les en-têtes en « En-têtes ».
Le libellé affecte également la recherche VoiceOver. L'utilisateur peut saisir un mot en mode recherche, et VoiceOver déplacera le focus sur l'élément avec un libellé correspondant. Par conséquent, les libellés doivent contenir des mots-clés que l'utilisateur recherchera.
Ajoutez la vérification des libellés au pipeline. Sur iOS, utilisez XCUITest avec fastlane scan. Sur Android, utilisez Accessibility Test Framework avec la règle AccessibilityCheckRule qui détecte les contentDescription vides. Cela évite les régressions lors de la fusion de nouveaux écrans.
Questions fréquentes
Label identifie l'élément (« Rechercher »), Hint explique le résultat de l'action (« Ouvre l'écran de recherche »). VoiceOver annonce le Label immédiatement lors de la mise au point, et le Hint en mode descriptions détaillées.
Sous iOS, UILabel obtient automatiquement un accessibilityLabel égal à son texte. Aucune configuration supplémentaire n'est nécessaire. Sous Android, TextView se comporte de manière similaire.
Définissez isAccessibilityElement = true sur la vue parent et remplacez accessibilityLabel, en renvoyant le texte concaténé des éléments enfants. Pour les composants complexes, utilisez la concaténation avec un séparateur.
Ajoutez du contexte aux éléments répétés : « Acheter iPhone 15 », « Acheter iPhone 15 Pro ». Automatisez la vérification via des tests UI — collectez tous les libellés et vérifiez l'absence de doublons.
Non. Pour masquer un élément, utilisez isAccessibilityElement = false sous iOS ou importantForAccessibility = « no » sous Android. Un libellé vide ne masque pas l'élément — le lecteur d'écran lira « sans titre ».
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