guides
Cuando tus mensajes de error excluyen a los usuarios
Los mensajes de error accesibles no consisten solo en añadir atributos ARIA. Esto es lo que realmente hace falta para diseñar errores que funcionen para todos.
El momento en que el formulario se rompe
Imagina esto: un usuario ciego rellena un formulario de pago, lo envía y no escucha nada útil en su lector de pantalla. Ningún anuncio. Ninguna explicación. La página ha marcado visualmente cinco errores de validación en rojo, pero el usuario no tiene ni idea. Vuelve a pulsar enviar. Y otra vez. Al final, se marcha.
No es un escenario marginal. La gestión inaccesible de errores es una de las barreras más comunes que encontramos en auditorías reales, y una de las que más frustra a los usuarios en el peor momento posible: cuando intentan completar una transacción o enviar algo importante.
La buena noticia es que solucionarlo consiste, en gran medida, en saber qué aspecto tiene lo «correcto». Los fallos son casi siempre los mismos pocos patrones.
Por qué los mensajes de error son difíciles para los usuarios de tecnologías de apoyo
Los usuarios videntes que usan ratón suelen detectar los errores de validación de inmediato: el borde rojo, el icono de advertencia, el texto que aparece debajo del campo. Pero los usuarios que dependen de lectores de pantalla, de la navegación por teclado o del control por voz se enfrentan a una experiencia fundamentalmente distinta.
Cuando se envía un formulario y aparecen errores:
- Los usuarios de lectores de pantalla pueden no escuchar nada a menos que el foco se mueva al error o una región activa lo anuncie
- Los usuarios de teclado necesitan poder alcanzar cada mensaje de error desde el teclado y entender a qué campo pertenece
- Los usuarios de control por voz necesitan referirse a los campos mediante una etiqueta visible y precisa; si la etiqueta es incorrecta o falta, se quedan atascados
Nada de esto ocurre automáticamente. Tienes que construirlo.
Los criterios de WCAG que aplican
Cuatro criterios de éxito de WCAG 2.2 cubren directamente la gestión de errores:
3.3.1 Identificación de errores (nivel A) — Si un error se detecta automáticamente, el elemento erróneo se identifica y se describe al usuario en texto. No puedes comunicar los errores solo mediante el color.
3.3.2 Etiquetas o instrucciones (nivel A) — Los campos que requieren un formato específico deben dejar claro ese requisito antes o durante la introducción de datos, no solo después de que el envío falle.
3.3.3 Sugerencias ante errores (nivel AA) — Si se detecta un error y se conocen sugerencias para corregirlo, proporciónalas. «Fecha no válida» no es suficiente. «Introduce la fecha en formato DD/MM/AAAA» sí lo es.
3.3.4 Prevención de errores (nivel AA) — Para los envíos con consecuencias importantes (transacciones financieras, acuerdos legales), da a los usuarios la posibilidad de revisar, corregir y confirmar antes de que la acción sea permanente.
También existe el criterio 4.1.3 Mensajes de estado (nivel AA), que cubre los mensajes inyectados dinámicamente que no reciben el foco: deben ser anunciados por las tecnologías de apoyo usando role="status" o role="alert".
Lo que realmente necesita un mensaje de error accesible
Hacer bien los mensajes de error requiere prestar atención a cuatro capas distintas:
1. La conexión programática
Cada mensaje de error debe estar vinculado a su campo mediante aria-describedby. Esto indica a los lectores de pantalla que anuncien el texto del error cuando el campo recibe el foco.
<!-- Before: error text exists visually but is invisible to screen readers -->
<label for="email">Email</label>
<input type="email" id="email" class="error">
<p class="error-text">Enter a valid email address.</p>
<!-- After: programmatic association via aria-describedby -->
<label for="email">Email address</label>
<input
type="email"
id="email"
aria-describedby="email-err"
aria-invalid="true"
>
<p id="email-err" class="error-text">Enter a valid email address.</p>
El atributo aria-invalid="true" indica que el campo es actualmente inválido, algo que la mayoría de los lectores de pantalla anuncian cuando el foco llega a él.
2. Gestión del foco tras el envío
Cuando un formulario se envía y hay errores presentes, el foco debe moverse a algún lugar útil. Los dos patrones más comunes:
- Mover el foco a un resumen de errores en la parte superior del formulario que liste todos los errores con enlaces a los campos correspondientes
- Mover el foco al primer campo con error
Si el foco se queda en el botón de envío o en ningún sitio, los usuarios de lectores de pantalla tienen que descubrir los errores por sí mismos navegando por el formulario, si es que llegan a saber que existen.
// After validation fails, move focus to the error summary
const summary = document.getElementById('error-summary');
summary.setAttribute('tabindex', '-1');
summary.focus();
3. Anuncios con regiones activas para errores dinámicos
Para los errores que aparecen mientras el usuario escribe (validación en tiempo real en línea), usa regiones activas de ARIA para que el mensaje se anuncie sin necesidad de mover el foco.
<p role="alert" aria-live="assertive" id="password-err">
Password must be at least 8 characters.
</p>
Usa role="alert" / aria-live="assertive" para errores que requieren atención inmediata. Usa role="status" / aria-live="polite" para avisos menos urgentes que pueden esperar a que el usuario haga una pausa.
4. El propio mensaje de error
El lenguaje importa. Los mensajes de error accesibles son:
- Específicos: dicen qué está mal, no solo que algo está mal
- Accionables: dicen al usuario exactamente qué hacer para solucionarlo
- Corteses: evitan el lenguaje acusatorio como «has introducido un valor no válido»
| Inaccesible | Accesible |
|---|---|
| «Entrada no válida» | «La dirección de correo electrónico debe incluir un símbolo @, p. ej., nombre@ejemplo.com» |
| «Error» | «La fecha debe estar en formato DD/MM/AAAA» |
| «Campo obligatorio» | «El nombre completo es obligatorio» |
| «Contraseña no válida» | «La contraseña debe tener al menos 8 caracteres e incluir un número» |
Patrones para distintos escenarios de error
Errores en línea junto al campo
El patrón más común. Un mensaje de error aparece directamente debajo del campo asociado. Funciona bien en formularios simples. Requiere aria-describedby y aria-invalid para anunciarse correctamente.
Banners de resumen de errores
Para formularios largos con múltiples errores, coloca un resumen en la parte superior que liste todos los problemas como enlaces que saltan al campo correspondiente. Mueve el foco aquí tras un envío fallido. Es el patrón que usa GOV.UK y el más recomendado para formularios complejos.
Notificaciones toast
Los mensajes efímeros que aparecen en el borde de la pantalla se encuentran entre los patrones más inaccesibles de uso común. Desaparecen antes de que los usuarios de lectores de pantalla puedan alcanzarlos, a menudo no se anuncian en absoluto y no ofrecen ninguna vía de recuperación. Evita usar toasts para errores. Si los usas, acompáñalos de un estado de error persistente en el propio formulario.
Errores del sistema
Cuando algo falla en el lado del servidor, explica al usuario en lenguaje sencillo qué ha ocurrido y qué puede hacer a continuación. «Algo ha salido mal» sin más orientación deja a los usuarios abandonados.
<div role="alert" aria-live="assertive">
<p>We couldn't save your changes due to a network error.
Please check your connection and try again.</p>
</div>
La lista de verificación de pruebas
Después de implementar la gestión de errores, verifica esto manualmente; las herramientas automáticas no detectarán la mayoría de estos puntos:
- Enviar un formulario obligatorio vacío mueve el foco a un resumen de errores o al primer campo con error
- Cada mensaje de error está vinculado a su campo mediante
aria-describedby - Los campos con error tienen
aria-invalid="true" - Los mensajes de error se anuncian cuando el foco llega al campo afectado
- La validación en tiempo real usa regiones activas
- Los mensajes de error usan un lenguaje específico y accionable, no solo «no válido»
- El color no es la única forma de indicar los errores (icono o etiqueta de texto junto al rojo)
- Se puede llegar al error tabulando con el teclado
- El orden del foco tras el envío es lógico y no salta de forma impredecible
- Los mensajes toast van acompañados de un estado de error persistente
Por qué las herramientas automáticas pasan por alto la mayoría de esto
Un escáner automático puede comprobar si aria-describedby apunta a un elemento existente y si aria-invalid está presente. No puede comprobar si el foco se mueve correctamente tras el envío, si el texto del error es preciso o si una notificación toast desaparece antes de poder leerse. Nuestras auditorías manuales de accesibilidad incluyen pruebas específicas de formularios con tecnologías de apoyo reales: la única forma fiable de verificar que la gestión de errores funciona de verdad de principio a fin.
Si no sabes en qué punto están tus formularios, ejecuta un análisis gratuito para sacar a la luz primero los problemas detectables automáticamente y continúa a partir de ahí.
Encuentra los problemas de accesibilidad de tus formularios antes que tus usuarios