Content Description è una proprietà di accessibilità che trasmette una descrizione testuale del contenuto non testuale alle tecnologie assistive. In iOS è l'attributo accessibilityHint per UIView, in Android — contentDescription nel markup XML. Secondo W3C WCAG 2.2, 2023, l'assenza di alternative testuali per il contenuto non testuale è una delle violazioni di accessibilità più comuni nelle applicazioni mobili. Le descrizioni correttamente compilate rendono l'app accessibile per le persone con disabilità visive che usano VoiceOver e TalkBack.
Punti chiave
Content Description è una proprietà stringa di un elemento dell'interfaccia che fornisce una rappresentazione testuale del contenuto visivo alle tecnologie assistive. Un lettore di schermo (VoiceOver su iOS, TalkBack su Android) legge la descrizione ad alta voce invece di tentare di riconoscere l'elemento visivamente. Le descrizioni vengono applicate a immagini senza strato di testo, icone, grafici, controlli personalizzati e qualsiasi elemento non testuale.
Secondo Google Material Design, 2024, gli elementi senza contentDescription violano WCAG 1.1.1 (Non-text Content). I controlli di Accessibility Scanner mostrano che fino al 40% delle icone nelle app di shopping non hanno descrizioni. Un utente VoiceOver sente “immagine” o “pulsante” senza specifiche — un'interfaccia del genere diventa inutilizzabile per la navigazione.
Content Description non sostituisce il testo visibile di un elemento. Se un pulsante contiene l'etichetta di testo “Invia,” non è necessario impostare una descrizione aggiuntiva — il lettore di schermo leggerà il testo. Per immagini, icone e campi di input, la descrizione è obbligatoria.
Gli strumenti Accessibility Scanner (Android) e Xcode Accessibility Inspector (iOS) verificano automaticamente la presenza di descrizioni. Si consiglia di eseguire questi controlli su ogni schermata prima del rilascio.
Un utente con disabilità visiva dipende da VoiceOver per comprendere l'interfaccia. Se un'icona del carrello non ha descrizione, sente solo “pulsante.” Per scoprire cosa fa il pulsante, deve toccarlo alla cieca — rischiando un'azione irreversibile. Una descrizione come “Rimuovi articolo dal carrello” risolve questo problema in un secondo.
Un utente con limitazioni temporanee (sole forte all'aperto, schermo rotto) usa anche VoiceOver. Secondo Apple Accessibility Report, 2023, circa il 20% degli utenti VoiceOver non ha disabilità visive permanenti — attivano la funzione situazionalmente.
Il criterio WCAG 1.1.1 (Livello A) richiede che tutto il contenuto non testuale abbia un'alternativa testuale. Eccezione: contenuto decorativo, utilizzato solo per la presentazione visiva o che non trasmette informazioni. Il test di decoratività: se rimuovi l'elemento, il significato della pagina cambia? Se no — può essere nascosto al lettore di schermo.
Accessibility Label (accessibilityLabel in iOS) è il nome dell'elemento che il lettore di schermo pronuncia al ricevere il focus. Content Description (accessibilityHint in iOS) è un chiarimento aggiuntivo annunciato dopo il nome che comunica il risultato di un'azione.
La differenza è chiara con l'esempio di un pulsante “Carrello”. Label: “Carrello.” Description: “Aprirà la schermata di pagamento.” VoiceOver dice: “Carrello. Aprirà la schermata di pagamento.” Se solo Label è impostato, l'utente non saprà cosa succede dopo aver toccato.
| Proprietà | iOS | Android | Scopo |
|---|---|---|---|
| Label | accessibilityLabel | contentDescription | Nome dell'elemento (pulsante, campo, immagine) |
| Description | accessibilityHint | contentDescription (estesa) | Chiarimento dell'azione o del significato |
| Trait | accessibilityTraits | role / className | Ruolo dell'elemento (pulsante, intestazione) |
Regola: Label risponde a “Cos'è?”, Description risponde a “Cosa succederà?” In Android, contentDescription può svolgere entrambi i ruoli, ma in pratica è meglio separarli: usare la concatenazione “[nome], [spiegazione].”
Per i gesti complessi (scorrere per eliminare, pressione lunga per menu contestuale), accessibilityHint è obbligatorio. Un utente VoiceOver non conosce i gesti nascosti se non vengono descritti. Specifica: “Scorri a sinistra per eliminare” nell'hint dell'elemento.
Sulla piattaforma iOS, accessibilityHint viene impostato tramite l'omonima proprietà di UIView o NSObject. Il valore è una stringa fino a 80 caratteri. VoiceOver legge l'hint dopo il label quando la modalità di descrizioni dettagliate è attivata (nelle impostazioni VoiceOver — “Verbosity”).
Esempio di impostazione dell'hint per un pulsante personalizzato:
import UIKit
class CustomButton: UIButton {
override func awakeFromNib() {
super.awakeFromNib()
self.accessibilityLabel = "Aggiungi ai preferiti"
self.accessibilityHint = "Salverà l'articolo nell'elenco dei preferiti"
}
}
Per UIImageView senza contenuto testuale, è obbligatorio impostare isAccessibilityElement = true e accessibilityHint:
let imageView = UIImageView(image: UIImage(named: "chart-sales"))
imageView.isAccessibilityElement = true
imageView.accessibilityHint = "Grafico delle vendite dell'ultimo trimestre"
VoiceOver legge: “Grafico delle vendite dell'ultimo trimestre.” Se l'hint è vuoto — solo “immagine.” Apple HIG, 2024 raccomanda di non usare verbi come “tocca” o “premi” negli hint — VoiceOver aggiunge automaticamente un'istruzione gestuale.
In SwiftUI, l'hint viene impostato tramite un modificatore a catena:
Image(systemName: "trash")
.accessibilityLabel("Elimina")
.accessibilityHint("Eliminerà permanentemente l'elemento selezionato")
SwiftUI combina automaticamente i modificatori per le viste composte. Se un Image si trova all'interno di un Button, SwiftUI usa l'etichetta del pulsante come accessibilityLabel principale.
Su Android, contentDescription viene impostato o nel markup XML o programmaticamente tramite setContentDescription(). TalkBack annuncia la descrizione quando l'elemento riceve il focus.
Esempio in XML:
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_search"
android:contentDescription="Cerca prodotti" />
Impostazione programmatica per elementi dinamici:
binding.iconSearch.contentDescription =
"Cerca. Aprirà la schermata di ricerca con filtri"
Per le immagini decorative (separatori, sfondi, icone decorative) imposta contentDescription = "@null" o setContentDescription(null) — TalkBack salterà tali elementi. In XML: android:contentDescription="@null". Una stringa vuota "" non funziona — TalkBack annuncerà comunque “immagine.”
Per ImageButton, imposta sempre contentDescription — TalkBack non vede il testo sulle immagini. Per CheckBox, la descrizione deve cambiare dinamicamente: “Selezionato” / “Non selezionato” invece di una descrizione statica. Usa setContentDescription nel listener di stato.
Informatività — la descrizione deve trasmettere significato, non aspetto. Non “Icona blu con un segno di spunta,” ma “Articolo aggiunto al carrello.” Un lettore di schermo non si interessa ai colori — si interessa al risultato.
Concisione — la lunghezza ottimale è 2–4 parole (fino a 80 caratteri). Le descrizioni lunghe rallentano la navigazione: VoiceOver legge sequenzialmente, ogni parola è un secondo del tempo dell'utente. Secondo Apple WWDC 2023, “Accessibility by Design”, una frase che richiede più di 5 secondi per essere letta interrompe il flusso cognitivo.
Unicità — non ci devono essere due elementi sullo stesso schermo con la stessa descrizione. L'utente non sarà in grado di distinguere quale risultato provocherà il focus sul primo elemento rispetto al secondo. Se ci sono più pulsanti “Acquista,” aggiungi un identificatore: “Acquista iPhone 15,” “Acquista iPhone 15 Pro.”
Localizzazione — Content Description deve essere tradotto in tutte le lingue supportate dall'app. Un errore di localizzazione nelle descrizioni è una delle cause comuni di fallimento di un'Accessibility Review nell'App Store.
Una ricerca di Nielsen Norman Group, 2024 ha mostrato che la lunghezza ottimale della descrizione per i lettori di schermo è di 3–5 parole (fino a 50 caratteri). Descrizioni più lunghe riducono la velocità di navigazione del 30%, poiché l'utente deve attendere la fine dell'annuncio prima del passo successivo.
Ridondanza — la descrizione duplica il testo visibile. Se un pulsante contiene il testo “Invia,” non impostare accessibilityHint = “Pulsante invia.” VoiceOver leggerà il testo automaticamente e l'hint aggiungerà rumore non necessario.
Confusione con Label — usare contentDescription invece di label per i pulsanti di testo. In iOS, accessibilityLabel deve corrispondere al testo del pulsante (o essere vuoto se il testo è già visibile), e l'hint deve solo chiarire l'azione. Secondo Google Testing Blog, 2024, il 23% delle app esaminate nel Play Store hanno descrizioni duplicate.
Ignorare la dinamica — la descrizione non viene aggiornata quando lo stato cambia. Ad esempio, la descrizione di un interruttore “Wi-Fi” rimane “Attiva Wi-Fi” anche dopo essere stato acceso. Approccio corretto: cambiare dinamicamente la descrizione in “Disattiva Wi-Fi” osservando lo stato.
Dopo un aggiornamento del design (cambio di icone, riorganizzazione degli elementi), Content Description spesso si perde. Motivo: il designer sostituisce un'immagine e lo sviluppatore non controlla le proprietà di accessibilità della nuova risorsa. Soluzione: rendere il controllo dell'accessibilità un passaggio obbligatorio nella revisione del codice — aggiungere un elemento checklist: “Content Description è stato aggiornato?”
func testContentDescriptionExists() {
let app = XCUIApplication()
app.launch()
let image = app.images["chart-sales"]
XCTAssertNotNil(image.label)
XCTAssertGreaterThan(image.label.count, 0)
}
Domande frequenti
VoiceOver o TalkBack annuncerà semplicemente “immagine” o “pulsante” senza indicarne lo scopo. Questo viola WCAG 1.1.1 e rende l'app inaccessibile per le persone con disabilità visive.
No. Se il pulsante ha un'etichetta di testo, VoiceOver la legge automaticamente. Una descrizione (accessibilityHint) può essere aggiunta per chiarire il risultato del tocco, ma Label non è richiesto.
In iOS imposta isAccessibilityElement = false. In Android imposta contentDescription = "@null". Il lettore di schermo salterà completamente questi elementi senza emettere suoni.
In iOS usa NSLocalizedString per accessibilityHint, in Android — risorse stringa tramite @string/. La traduzione delle descrizioni è obbligatoria per tutte le lingue supportate.
Aggiungi test UI che verifichino la presenza di descrizioni per tutti gli ImageView. In iOS — XCUIApplication, in Android — AccessibilityCheckRule da Espresso. Accessibility Scanner può essere eseguito in CI tramite riga di comando.
Riepilogo
Svilupperemo un'applicazione mobile chiavi in mano
IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.
Leggi anche