Content Description es una propiedad de accesibilidad que transmite una descripción textual del contenido no textual a las tecnologías de asistencia. En iOS es el atributo accessibilityHint para UIView, en Android — contentDescription en el marcado XML. Según W3C WCAG 2.2, 2023, la ausencia de alternativas textuales para contenido no textual es una de las violaciones de accesibilidad más comunes en aplicaciones móviles. Las descripciones correctamente cumplimentadas hacen que la aplicación sea accesible para personas con discapacidad visual que usan VoiceOver y TalkBack.
Puntos clave
Content Description es una propiedad de cadena de un elemento de la interfaz que proporciona una representación textual del contenido visual a las tecnologías de asistencia. Un lector de pantalla (VoiceOver en iOS, TalkBack en Android) lee la descripción en voz alta en lugar de intentar reconocer el elemento visualmente. Las descripciones se aplican a imágenes sin capa de texto, iconos, gráficos, controles personalizados y cualquier elemento no textual.
Según Google Material Design, 2024, los elementos sin contentDescription violan WCAG 1.1.1 (Non-text Content). Las comprobaciones de Accessibility Scanner muestran que hasta el 40% de los iconos en aplicaciones de compras carecen de descripciones. Un usuario de VoiceOver escucha “imagen” o “botón” sin más detalles — una interfaz así se vuelve inutilizable para la navegación.
Content Description no reemplaza el texto visible de un elemento. Si un botón contiene la etiqueta de texto “Enviar,” no es necesario establecer una descripción adicional — el lector de pantalla leerá el texto. Para imágenes, iconos y campos de entrada, la descripción es obligatoria.
Las herramientas Accessibility Scanner (Android) y Xcode Accessibility Inspector (iOS) verifican automáticamente la presencia de descripciones. Se recomienda ejecutar estas comprobaciones en cada pantalla antes del lanzamiento.
Un usuario con discapacidad visual depende de VoiceOver para entender la interfaz. Si un icono de carrito de compras no tiene descripción, solo escucha “botón.” Para saber qué hace el botón, tiene que pulsarlo a ciegas — arriesgando una acción irreversible. Una descripción como “Eliminar artículo del carrito” resuelve este problema en un segundo.
Un usuario con limitaciones temporales (sol brillante en la calle, pantalla rota) también usa VoiceOver. Según Apple Accessibility Report, 2023, alrededor del 20% de los usuarios de VoiceOver no tienen discapacidades visuales permanentes — activan la función situacionalmente.
El criterio WCAG 1.1.1 (Nivel A) exige que todo contenido no textual tenga una alternativa textual. Excepción: contenido que sea decorativo, utilizado solo para presentación visual o que no transmita información. La prueba de decoratividad: si eliminas el elemento, ¿cambia el significado de la página? Si no — se puede ocultar al lector de pantalla.
Accessibility Label (accessibilityLabel en iOS) es el nombre del elemento que el lector de pantalla pronuncia al recibir el foco. Content Description (accessibilityHint en iOS) es una aclaración adicional que se anuncia después del nombre y comunica el resultado de una acción.
La diferencia se ve claramente con el ejemplo de un botón “Carrito”. Label: “Carrito.” Description: “Abrirá la pantalla de pago.” VoiceOver dice: “Carrito. Abrirá la pantalla de pago.” Si solo se configura Label, el usuario no sabrá qué ocurre después de pulsar.
| Propiedad | iOS | Android | Propósito |
|---|---|---|---|
| Label | accessibilityLabel | contentDescription | Nombre del elemento (botón, campo, imagen) |
| Description | accessibilityHint | contentDescription (extendida) | Aclaración de la acción o significado |
| Trait | accessibilityTraits | role / className | Rol del elemento (botón, encabezado) |
Regla: Label responde a “¿Qué es esto?”, Description responde a “¿Qué ocurrirá?” En Android, contentDescription puede cumplir ambas funciones, pero en la práctica es mejor separarlas: usar la concatenación “[nombre], [explicación].”
Para gestos complejos (deslizar para eliminar, pulsación larga para menú contextual), accessibilityHint es obligatorio. Un usuario de VoiceOver no conoce los gestos ocultos si no están descritos. Indica: “Desliza a la izquierda para eliminar” en el hint del elemento.
En la plataforma iOS, accessibilityHint se establece mediante la propiedad homónima de UIView o NSObject. El valor es una cadena de hasta 80 caracteres. VoiceOver lee el hint después del label cuando el modo de descripciones detalladas está activado (en los ajustes de VoiceOver — “Verbosity”).
Ejemplo de configuración de hint para un botón personalizado:
import UIKit
class CustomButton: UIButton {
override func awakeFromNib() {
super.awakeFromNib()
self.accessibilityLabel = "Agregar a favoritos"
self.accessibilityHint = "Guardará el producto en la lista de favoritos"
}
}
Para UIImageView sin contenido textual, es obligatorio establecer isAccessibilityElement = true y accessibilityHint:
let imageView = UIImageView(image: UIImage(named: "chart-sales"))
imageView.isAccessibilityElement = true
imageView.accessibilityHint = "Gráfico de ventas del último trimestre"
VoiceOver lee: “Gráfico de ventas del último trimestre.” Si el hint está vacío — solo “imagen.” Apple HIG, 2024 recomienda no usar verbos como “toca” o “pulsa” en los hints — VoiceOver añade automáticamente una instrucción de gesto.
En SwiftUI, el hint se establece mediante un modificador en cadena:
Image(systemName: "trash")
.accessibilityLabel("Eliminar")
.accessibilityHint("Eliminará permanentemente el elemento seleccionado")
SwiftUI combina automáticamente los modificadores para vistas compuestas. Si una Image está dentro de un Button, SwiftUI usa la etiqueta del botón como accessibilityLabel principal.
En Android, contentDescription se establece ya sea en el marcado XML o mediante programación con setContentDescription(). TalkBack anuncia la descripción cuando el elemento recibe el foco.
Ejemplo en XML:
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_search"
android:contentDescription="Buscar productos" />
Configuración programática para elementos dinámicos:
binding.iconSearch.contentDescription =
"Buscar. Abrirá la pantalla de búsqueda con filtros"
Para imágenes decorativas (separadores, fondos, iconos decorativos) establece contentDescription = "@null" o setContentDescription(null) — TalkBack omitirá dichos elementos. En XML: android:contentDescription="@null". Una cadena vacía "" no funciona — TalkBack seguirá anunciando “imagen.”
Para ImageButton, establece siempre contentDescription — TalkBack no ve el texto en las imágenes. Para CheckBox, la descripción debe cambiar dinámicamente: “Seleccionado” / “No seleccionado” en lugar de una descripción estática. Usa setContentDescription en el listener de estado.
Informatividad — la descripción debe transmitir significado, no apariencia. No “Icono azul con una marca de verificación,” sino “Artículo añadido al carrito.” Un lector de pantalla no se interesa por los colores — se interesa por el resultado.
Brevedad — la longitud óptima es de 2 a 4 palabras (hasta 80 caracteres). Las descripciones largas ralentizan la navegación: VoiceOver lee secuencialmente, cada palabra es un segundo del tiempo del usuario. Según Apple WWDC 2023, “Accessibility by Design”, una frase que requiere más de 5 segundos de lectura interrumpe el flujo cognitivo.
Unicidad — no debe haber dos elementos en la misma pantalla con la misma descripción. El usuario no podrá distinguir qué resultado provocará el foco en el primer elemento frente al segundo. Si hay varios botones “Comprar,” añade un identificador: “Comprar iPhone 15,” “Comprar iPhone 15 Pro.”
Localización — Content Description debe traducirse a todos los idiomas que soporte la aplicación. Un error de localización en las descripciones es una de las causas comunes de fracaso de una Accessibility Review en la App Store.
Una investigación de Nielsen Norman Group, 2024 mostró que la longitud óptima de la descripción para lectores de pantalla es de 3 a 5 palabras (hasta 50 caracteres). Las descripciones más largas reducen la velocidad de navegación en un 30%, ya que el usuario tiene que esperar a que termine el anuncio antes del siguiente paso.
Redundancia — la descripción duplica el texto visible. Si un botón contiene el texto “Enviar,” no establezcas accessibilityHint = “Botón enviar.” VoiceOver leerá el texto automáticamente, y el hint añadirá ruido innecesario.
Confusión con Label — usar contentDescription en lugar de label para botones de texto. En iOS, accessibilityLabel debe coincidir con el texto del botón (o estar vacío si el texto ya es visible), y el hint solo debe aclarar la acción. Según Google Testing Blog, 2024, el 23% de las aplicaciones revisadas en Play Store tienen descripciones duplicadas.
Ignorar la dinámica — la descripción no se actualiza cuando cambia el estado. Por ejemplo, la descripción de un interruptor “Wi-Fi” sigue siendo “Activar Wi-Fi” incluso después de encenderse. Enfoque correcto: cambiar dinámicamente la descripción a “Desactivar Wi-Fi” mediante la observación del estado.
Después de una actualización de diseño (cambio de iconos, reorganización de elementos), Content Description a menudo se pierde. Motivo: el diseñador reemplaza una imagen y el desarrollador no verifica las propiedades de accesibilidad del nuevo recurso. Solución: hacer que la verificación de accesibilidad sea un paso obligatorio en la revisión de código — añadir un elemento de lista de verificación: “¿Se ha actualizado Content Description?”
func testContentDescriptionExists() {
let app = XCUIApplication()
app.launch()
let image = app.images["chart-sales"]
XCTAssertNotNil(image.label)
XCTAssertGreaterThan(image.label.count, 0)
}
Preguntas frecuentes
VoiceOver o TalkBack simplemente anunciarán “imagen” o “botón” sin indicar su propósito. Esto viola WCAG 1.1.1 y hace que la aplicación sea inaccesible para personas con discapacidad visual.
No. Si el botón tiene una etiqueta de texto, VoiceOver la lee automáticamente. Se puede añadir una descripción (accessibilityHint) para aclarar el resultado de la pulsación, pero no se requiere Label.
En iOS establece isAccessibilityElement = false. En Android establece contentDescription = "@null". El lector de pantalla omitirá completamente estos elementos sin emitir sonido.
En iOS usa NSLocalizedString para accessibilityHint, en Android — recursos de cadena mediante @string/. La traducción de las descripciones es obligatoria para todos los idiomas soportados.
Añade pruebas de IU que verifiquen la existencia de descripciones en todos los ImageView. En iOS — XCUIApplication, en Android — AccessibilityCheckRule de Espresso. Accessibility Scanner se puede ejecutar en CI mediante la línea de comandos.
Resumen
Desarrollaremos una aplicación móvil llave en mano
IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.
Lea también