Accesibilidad (WCAG 2.2)
Esta habilidad garantiza que las interfaces digitales sean Perceptibles, Operables, Comprensibles y Robustas (POUR) para todos los usuarios, incluidos aquellos que utilizan lectores de pantalla, controles de interruptor o navegación por teclado. Se centra en la implementación técnica de los criterios de éxito de WCAG 2.2.
Cuándo Usarlo
- Definir especificaciones de componentes de UI para Web, iOS o Android.
- Auditar código existente en busca de barreras de accesibilidad o brechas de cumplimiento.
- Implementar nuevos estándares de WCAG 2.2 como Tamaño de Objetivo (Mínimo) y Apariencia del Foco.
- Mapear requisitos de diseño de alto nivel a atributos técnicos (roles ARIA, traits y pistas).
Conceptos Clave
- Principios POUR: La base de WCAG (Perceptible, Operable, Comprensible, Robusto).
- Mapeo Semántico: Usar elementos nativos en lugar de contenedores genéricos para proporcionar accesibilidad incorporada.
- Árbol de Accesibilidad: La representación de la UI que las tecnologías de asistencia "leen" realmente.
- Gestión del Foco: Controlar el orden y la visibilidad del cursor del teclado/lector de pantalla.
- Etiquetas y Pistas: Proporcionar contexto mediante
aria-label,accessibilityLabelycontentDescription.
Cómo Funciona
Paso 1: Identificar el Rol del Componente
Determinar el propósito funcional (por ejemplo, ¿Es un botón, un enlace o una pestaña?). Usar el elemento nativo más semántico disponible antes de recurrir a roles personalizados.
Paso 2: Definir Atributos Perceptibles
- Asegurar que el contraste del texto cumpla con 4.5:1 (normal) o 3:1 (grande/UI).
- Agregar alternativas de texto para contenido no textual (imágenes, iconos).
- Implementar reflujo responsivo (hasta un 400% de zoom sin pérdida de función).
Paso 3: Implementar Controles Operables
- Asegurar un tamaño mínimo de objetivo de 24x24 píxeles CSS (WCAG 2.2 SC 2.5.8).
- Verificar que todos los elementos interactivos sean alcanzables mediante teclado y tengan un indicador de foco visible (SC 2.4.11).
- Proporcionar alternativas de un solo puntero para movimientos de arrastre.
Paso 4: Asegurar Lógica Comprensible
- Usar patrones de navegación consistentes.
- Proporcionar mensajes de error descriptivos y sugerencias para la corrección (SC 3.3.3).
- Implementar "Entrada Redundante" (SC 3.3.7) para evitar solicitar los mismos datos dos veces.
Paso 5: Verificar Compatibilidad Robusta
- Usar patrones correctos de
Nombre, Rol, Valor. - Implementar
aria-liveo regiones en vivo para actualizaciones de estado dinámicas.
Diagrama de Arquitectura de Accesibilidad
flowchart TD
UI["Componente UI"] --> Platform{¿Plataforma?}
Platform -->|Web| ARIA["WAI-ARIA + HTML5"]
Platform -->|iOS| SwiftUI["Traits de Accesibilidad + Etiquetas"]
Platform -->|Android| Compose["Semántica + ContentDesc"]
ARIA --> AT["Tecnología de Asistencia (Lectores de pantalla, Interruptores)"]
SwiftUI --> AT
Compose --> AT
Mapeo Multiplataforma
| Característica | Web (HTML/ARIA) | iOS (SwiftUI) | Android (Compose) |
|---|---|---|---|
| Etiqueta Principal | aria-label / <label> | .accessibilityLabel() | contentDescription |
| Pista Secundaria | aria-describedby | .accessibilityHint() | Modifier.semantics { stateDescription = ... } |
| Rol de Acción | role="button" | .accessibilityAddTraits(.isButton) | Modifier.semantics { role = Role.Button } |
| Actualizaciones en Vivo | aria-live="polite" | .accessibilityLiveRegion(.polite) | Modifier.semantics { liveRegion = LiveRegionMode.Polite } |
Ejemplos
Web: Búsqueda Accesible
<form role="search">
<label for="search-input" class="sr-only">Buscar productos</label>
<input type="search" id="search-input" placeholder="Buscar..." />
<button type="submit" aria-label="Enviar búsqueda">
<svg aria-hidden="true">...</svg>
</button>
</form>
iOS: Botón de Acción Accesible
Button(action: deleteItem) {
Image(systemName: "trash")
}
.accessibilityLabel("Eliminar elemento")
.accessibilityHint("Elimina permanentemente este elemento de tu lista")
.accessibilityAddTraits(.isButton)
Android: Alternador Accesible
Switch(
checked = isEnabled,
onCheckedChange = { onToggle() },
modifier = Modifier.semantics {
contentDescription = "Activar notificaciones"
}
)
Antipatrones a Evitar
- Div-Botones: Usar un
<div>o<span>para un evento de clic sin agregar un rol y soporte de teclado. - Significado Solo por Color: Indicar un error o estado únicamente mediante un cambio de color (por ejemplo, volver un borde rojo).
- Foco de Modal Sin Contención: Modales que no atrapan el foco, permitiendo que los usuarios de teclado naveguen por el contenido de fondo mientras el modal está abierto. El foco debe estar contenido y ser escapable mediante la tecla
Escapeo un botón de cierre explícito (SC WCAG 2.1.2). - Texto Alternativo Redundante: Usar "Imagen de..." o "Foto de..." en el texto alt (los lectores de pantalla ya anuncian el rol "Imagen").
Lista de Verificación de Buenas Prácticas
- Los elementos interactivos cumplen con el tamaño de objetivo de 24x24px (Web) o 44x44pt (Nativo).
- Los indicadores de foco son claramente visibles y de alto contraste.
- Los modales contienen el foco mientras están abiertos y lo liberan limpiamente al cerrarse (tecla
Escapeo botón de cierre). - Los menús desplegables restauran el foco al elemento disparador al cerrarse.
- Los formularios proporcionan sugerencias de error basadas en texto.
- Todos los botones de solo icono tienen una etiqueta de texto descriptiva.
- El contenido refluye correctamente cuando se escala el texto.
Referencias
- Guías WCAG 2.2
- Prácticas de Autoría WAI-ARIA
- Guía de Programación de Accesibilidad de iOS
- Guía de Interfaz Humana de iOS - Accesibilidad
- Guía de Desarrollador de Accesibilidad de Android
Habilidades Relacionadas
frontend-patternsdesign-systemliquid-glass-designswiftui-patterns