Criterios de éxito de las WCAG · Level A
WCAG 3.3.1: Identificación de errores
WCAG 3.3.1 requiere que, cuando se detecta automáticamente un error de entrada, se identifique el elemento con error y se describa el error al usuario en texto. Esto garantiza que las personas con discapacidad puedan reconocer, comprender y corregir errores al completar formularios.
Qué significa esta regla
WCAG 3.3.1 Identificación de errores es un criterio de éxito de Nivel A bajo el principio de Comprensible. Establece: «Si se detecta automáticamente un error de entrada, se identifica el elemento que contiene el error y se describe el error al usuario mediante texto.» En términos prácticos, siempre que tu sitio web o aplicación valide automáticamente la entrada del usuario —ya sea al enviar el formulario, al perder el foco del campo o en tiempo real— deben ocurrir dos cosas si se detecta un error: el campo o control específico que contiene el error debe identificarse claramente, y la naturaleza del error debe comunicarse utilizando contenido de texto real (no únicamente color, icono o sonido).
El criterio se aplica a cualquier situación en la que se recopila entrada de usuarios y se realiza validación automática. Esto incluye elementos de formulario HTML como <input>, <select>, <textarea>, así como widgets interactivos personalizados construidos con ARIA. Cubre la validación del lado del cliente activada por JavaScript, la validación nativa del navegador mediante atributos como required, pattern, minlength y type, así como los resultados de validación del lado del servidor que se muestran tras recargar la página o se inyectan dinámicamente en el DOM.
Un cumplimiento requiere que: (1) cada campo con error esté asociado programáticamente con un mensaje de error —normalmente mediante aria-describedby o aria-errormessage— para que las tecnologías de asistencia puedan anunciarlo; (2) el mensaje de error sea texto en lenguaje sencillo visible en la interfaz (no oculto a las personas videntes); y (3) el texto describa claramente qué salió mal, no solo que algo salió mal. Por ejemplo, «Se requiere la dirección de correo electrónico» es una descripción de error válida, mientras que mostrar únicamente un borde rojo o un icono de exclamación sin alternativa textual es un incumplimiento.
Se produce un incumplimiento cuando: los errores se indican solo mediante cambios de color (borde rojo sin texto), los errores se anuncian únicamente mediante role="alert" sin identificar qué campo se ve afectado, el texto del mensaje de error está vacío o es genérico (por ejemplo, «Entrada no válida»), o los mensajes de error existen en el DOM pero no están vinculados programáticamente al campo correspondiente, de modo que los lectores de pantalla no pueden asociarlos.
WCAG 3.3.1 no se aplica cuando no se produce ninguna detección automática; por ejemplo, si se envía un formulario y el servidor simplemente recarga la página sin ninguna indicación de qué salió mal, eso es un fallo de usabilidad independiente pero queda fuera del alcance estricto de este criterio. Sin embargo, si tu sistema realiza detección automática (como prácticamente todos los formularios modernos), el criterio está plenamente dentro del alcance. No hay excepciones definidas dentro del propio criterio para tipos de entrada o casos de uso específicos.
Por qué es importante
La identificación de errores afecta directamente a múltiples grupos de personas con discapacidad de maneras significativas. Para personas ciegas y con baja visión que dependen de lectores de pantalla como NVDA, JAWS o VoiceOver, un borde rojo o un icono de advertencia no comunican nada. Si un mensaje de error no está presente como texto real y no está asociado programáticamente con el campo en error, el lector de pantalla no lo anunciará, y la persona puede enviar un formulario repetidamente sin entender por qué falla. Según la Organización Mundial de la Salud, aproximadamente 2,2 mil millones de personas en todo el mundo tienen algún tipo de discapacidad visual, y millones dependen diariamente de tecnología de asistencia para interactuar con contenido web.
Para personas con discapacidades cognitivas, incluidas la dislexia, el trastorno por déficit de atención y las alteraciones de la memoria, los mensajes de error vagos como «Algo salió mal» crean barreras significativas. Estas personas se benefician enormemente de texto de error preciso y descriptivo que les indique exactamente qué campo necesita corrección y cuál debe ser el formato o valor correcto. Por ejemplo, en lugar de «Fecha no válida», un mensaje como «La fecha de nacimiento debe estar en formato DD/MM/AAAA» es mucho más útil.
Las personas con discapacidades motoras que navegan con teclado o dispositivos de conmutación realizan un esfuerzo significativo al desplazarse por un formulario. Cuando un error es poco claro o no se identifica, deben volver a recorrer todo el formulario para encontrar el problema, lo que incrementa enormemente el coste cognitivo y físico de completar el formulario. Una identificación clara de errores permite a estas personas ir directamente al campo problemático.
Considera este escenario real: una persona ciudadana turca que intenta registrarse en un portal de servicios electrónicos del gobierno para solicitar una prestación por discapacidad. El formulario requiere un número de identificación nacional en un formato específico. La persona, que es ciega, introduce su número de identificación. Al enviar, el formulario se recarga con campos resaltados en rojo pero sin texto de error asociado. El lector de pantalla anuncia solo las etiquetas de los campos de nuevo; la persona no tiene idea de qué salió mal ni qué campo es el problemático. Abandona el proceso por completo, perdiendo el acceso a un servicio público fundamental. Esta es precisamente la situación que WCAG 3.3.1 está diseñada para evitar.
Más allá de la accesibilidad, una identificación clara de errores mejora las tasas de conversión y la usabilidad para todas las personas usuarias. Los estudios de investigación en UX muestran de forma consistente que los mensajes de error en línea y descriptivos reducen el abandono de formularios. Desde una perspectiva de SEO, las mejores señales de interacción —incluidos mayor tiempo en el sitio y formularios completados con éxito— influyen positivamente en el posicionamiento en buscadores con el tiempo.
Reglas relacionadas de Axe-core
WCAG 3.3.1 requiere pruebas manuales para una verificación completa. Esto se debe a que las herramientas automatizadas pueden detectar la presencia o ausencia de patrones estructurales (como aria-describedby o aria-errormessage), pero no pueden evaluar si el contenido textual de un mensaje de error es significativo, preciso o suficiente para ayudar a la persona usuaria a entender y corregir el error. Una herramienta automatizada ve que existe un elemento con role="alert"; no puede juzgar si el mensaje «Error en la línea 4» describe adecuadamente un fallo de validación a una persona usuaria de lector de pantalla.
- aria-required-attr: Esta regla de axe-core comprueba que los elementos con ciertos roles ARIA tengan presentes todos los atributos ARIA requeridos. Aunque no es exclusivamente una regla de identificación de errores, es relevante porque un campo de formulario en estado de error que usa
role="textbox"o similar sin los atributos requeridos puede no transmitir la información de estado a las tecnologías de asistencia, lo que socava la comunicación del error. - aria-valid-attr-value: Esta regla señala los casos en los que los atributos ARIA hacen referencia a IDs que no existen en el DOM. Por ejemplo, si un campo usa
aria-describedby="email-error"pero no existe ningún elemento conid="email-error", la asociación se rompe y el mensaje de error no será leído por los lectores de pantalla. Este es un patrón de fallo común para 3.3.1. - Requisito de evaluación manual: Las personas evaluadoras deben provocar manualmente errores de validación y luego usar un lector de pantalla para confirmar que: el campo con error se identifica por nombre o etiqueta, la descripción del error se anuncia, el mensaje es significativo y accionable, y el error no se comunica solo mediante medios no textuales. Los análisis automatizados no pueden simular secuencias de interacción de usuario ni evaluar la calidad semántica del texto del mensaje, por lo que el juicio humano es indispensable para este criterio.
Cómo probar
- Análisis automatizado con axe DevTools o Lighthouse: Ejecuta un análisis con axe DevTools en la página que contiene el formulario antes y después de provocar errores de validación. Busca específicamente infracciones relacionadas con referencias rotas de
aria-describedbyoaria-errormessage, regionesrole="alert"oaria-liveausentes que se usan para inyección dinámica de errores, y campos de formulario sin etiquetas (lo que también impide una asociación correcta de errores). En Lighthouse, revisa la auditoría de Accesibilidad para detectar infracciones relacionadas con formularios. Ten en cuenta que un informe automatizado limpio no confirma el cumplimiento de 3.3.1; solo descarta ciertos fallos estructurales. - Prueba manual de navegación con teclado: Usando solo el teclado (Tab, Shift+Tab, Enter, Espacio), intenta enviar el formulario con valores intencionalmente incorrectos o ausentes. Verifica que: el foco se mueva hacia o cerca del primer campo con error, cada mensaje de error sea visible en el área de visualización, y los mensajes de error identifiquen el campo específico por nombre y describan el problema en texto claro.
- Prueba con lector de pantalla usando NVDA + Firefox: Abre el formulario en Firefox con NVDA activo. Envía el formulario con errores. Escucha con atención: ¿anuncia NVDA qué campo tiene un error? ¿Se lee en voz alta la descripción del error? Sitúa el foco en el campo erróneo con Tab: ¿lee NVDA el mensaje de error asociado como parte de la descripción accesible del campo? Si se usan regiones
aria-live, verifica que el anuncio no se retrase ni se suprima. - Prueba con lector de pantalla usando VoiceOver + Safari (macOS/iOS): Repite el mismo proceso usando VoiceOver en Safari. Usa VO+Flecha derecha para leer el formulario tras el envío. Confirma que cada campo con error incluye el texto de error en su nombre o descripción accesible. En iOS, prueba usando navegación táctil y gestos de deslizamiento.
- Prueba con lector de pantalla usando JAWS + Chrome: Con JAWS ejecutándose en Chrome, envía el formulario con errores. Usa el cursor virtual de JAWS para navegar a cada campo de formulario con error. Confirma que el texto del mensaje de error se incluye en la lectura que hace JAWS del campo. Revisa también el comportamiento del modo formularios de JAWS, ya que este modo suprime algunos anuncios de regiones en vivo.
- Auditoría de color y señales no textuales: Inspecciona visualmente cada estado de error. Elimina o desactiva temporalmente el CSS (usando las herramientas de desarrollo del navegador o un bookmarklet) y confirma que la identificación del error sigue presente como texto en el DOM. Esto verifica que la comunicación del error no dependa únicamente del color o la iconografía.
- Comprobación de inyección dinámica: Para aplicaciones de una sola página o formularios con validación en tiempo real, usa las herramientas de desarrollo del navegador para inspeccionar el DOM después de que se haya provocado un error. Confirma que el elemento del mensaje de error existe en el DOM, contiene texto no vacío y está referenciado por la entrada correspondiente mediante
aria-describedbyoaria-errormessage.
Cómo corregir
Escenario 1: Error indicado solo por color — Incorrecto
<!-- Incumplimiento: borde rojo añadido mediante clase, sin texto de error asociado -->
<label for='email'>Email Address</label>
<input type='email' id='email' name='email' class='input-error'>
<!-- El CSS establece border: 2px solid red en .input-error -->
<!-- No se muestra ningún texto de mensaje de error en el DOM -->
Escenario 1: Error indicado solo por color — Correcto
<!-- Cumplimiento: el texto de error está presente, es visible y está vinculado al input -->
<label for='email'>Email Address</label>
<input
type='email'
id='email'
name='email'
class='input-error'
aria-describedby='email-error'
aria-invalid='true'
>
<!-- aria-invalid indica el estado de error a las tecnologías de asistencia -->
<!-- aria-describedby vincula el input con su mensaje de error mediante el ID -->
<p id='email-error' role='alert'>
Please enter a valid email address, for example: [email protected]
</p>
Escenario 2: Resumen genérico de errores sin identificación de campos — Incorrecto
<!-- Incumplimiento: existe una alerta de resumen pero no identifica qué campos fallaron -->
<div role='alert'>
<p>There are errors in the form. Please correct them and try again.</p>
</div>
<label for='phone'>Phone Number</label>
<input type='tel' id='phone' name='phone' class='is-invalid'>
<!-- No hay mensaje de error por campo; la persona usuaria no puede determinar qué campo falló -->
Escenario 2: Resumen genérico de errores sin identificación de campos — Correcto
<!-- Cumplimiento: el resumen enumera campos específicos con error y cada campo tiene texto de error en línea -->
<div role='alert' aria-labelledby='error-heading'>
<h2 id='error-heading'>2 errors found. Please fix the following:</h2>
<ul>
<li><a href='#phone'>Phone Number: must contain only digits and be 10 characters long</a></li>
<li><a href='#dob'>Date of Birth: required field — please enter your date of birth</a></li>
</ul>
</div>
<label for='phone'>Phone Number</label>
<input
type='tel'
id='phone'
name='phone'
aria-describedby='phone-error'
aria-invalid='true'
>
<!-- Mensaje de error en línea vinculado mediante aria-describedby -->
<p id='phone-error'>Phone Number must contain only digits and be 10 characters long.</p>
Escenario 3: Referencia aria-describedby rota — Incorrecto
<!-- Incumplimiento: aria-describedby hace referencia a un ID que no existe en el DOM -->
<label for='username'>Username</label>
<input
type='text'
id='username'
name='username'
aria-describedby='username-msg'
aria-invalid='true'
>
<!-- El elemento con id='username-msg' nunca se mostró o fue eliminado -->
<!-- Los lectores de pantalla no encuentran destino y no anuncian ninguna descripción -->
Escenario 3: Referencia aria-describedby rota — Correcto
<!-- Cumplimiento: el elemento referenciado existe en el DOM con un ID coincidente -->
<label for='username'>Username</label>
<input
type='text'
id='username'
name='username'
aria-describedby='username-msg'
aria-invalid='true'
>
<!-- El elemento con ID coincidente está presente y contiene texto descriptivo -->
<span id='username-msg'>
Username must be between 4 and 20 characters and contain only letters and numbers.
</span>
Escenario 4: Error de validación en tiempo real inyectado dinámicamente — Incorrecto
<!-- Incumplimiento: el error se inyecta en el DOM pero no se asocia al input; no hay región en vivo -->
<label for='password'>Password</label>
<input type='password' id='password' name='password'>
<!-- Tras perder el foco, JavaScript añade este elemento, pero no hay aria-describedby en el input -->
<div class='error-text'>Password is too short.</div>
Escenario 4: Error de validación en tiempo real inyectado dinámicamente — Correcto
<!-- Cumplimiento: el contenedor de error preexiste en el DOM (vacío), el input lo referencia; aria-live anuncia los cambios -->
<label for='password'>Password</label>
<input
type='password'
id='password'
name='password'
aria-describedby='password-error'
aria-invalid='false'
>
<!-- Span vacío presente al cargar la página; JavaScript rellena el texto y establece aria-invalid='true' en caso de error -->
<span id='password-error' aria-live='polite'></span>
<!-- JavaScript al perder el foco: -->
<!-- document.getElementById('password-error').textContent = 'Password must be at least 8 characters.'; -->
<!-- document.getElementById('password').setAttribute('aria-invalid', 'true'); -->
Errores comunes
- Usar solo cambios de clase CSS (por ejemplo, añadir
border-color: red) para indicar errores sin texto correspondiente en el DOM. El color por sí solo no es perceptible para personas ciegas o con daltonismo, y no cumple ni 3.3.1 ni 1.4.1. - Escribir
aria-describedbyen el input pero apuntar a un ID que se muestra de forma condicional o se elimina del DOM al restablecer la validación. La referencia rota implica que el lector de pantalla no encuentra contenido asociado y el error es, en la práctica, invisible para las personas usuarias de tecnología de asistencia. - Usar texto de
placeholdercomo único mensaje de error. El texto de placeholder desaparece cuando la persona empieza a escribir, suele tener bajo contraste y no siempre es anunciado de forma fiable por todos los lectores de pantalla como parte de la descripción del campo en estados de error. - Inyectar mensajes de error dinámicamente en el DOM sin asegurarse de que estén asociados a su campo padre mediante
aria-describedby. Un mensaje de error visualmente adyacente no se asocia automáticamente a un input; el vínculo programático debe ser explícito. - Mostrar un resumen de errores a nivel de página sin vincular cada elemento del resumen con el campo específico en error. Las personas usuarias de lectores de pantalla o navegación por teclado necesitan poder pasar directamente de la descripción del error al campo que requiere corrección.
- Establecer
aria-invalid='true'en un campo pero no proporcionar texto de mensaje de error. El atributoaria-invalidindica que un campo está en estado de error pero no describe el error; debe combinarse con un mensaje descriptivo. - Proporcionar mensajes de error demasiado genéricos, como «Entrada no válida» o «Error en el campo». Estas descripciones no explican qué está mal ni cómo solucionarlo, incumplen el requisito descriptivo de 3.3.1 y hacen que la corrección de errores sea innecesariamente difícil para todas las personas usuarias.
- Eliminar regiones
aria-liveorole='alert'de los contenedores de error al restablecer un formulario, haciendo que los contenedores desaparezcan antes de que los lectores de pantalla terminen de anunciar su contenido. Los anuncios de error pueden cortarse, dejando a la persona sin saber el resultado de la validación. - Confiar en las burbujas de validación nativas del navegador (las ventanas emergentes predeterminadas) sin personalización. Las interfaces de validación nativas del navegador son inconsistentes entre navegadores y combinaciones de tecnologías de asistencia, y a menudo no cumplen los requisitos de WCAG para identificación y descripción en escenarios de formularios complejos.
- Colocar mensajes de error visualmente lejos de sus campos asociados —como solo en una caja de alerta en el encabezado— sin proporcionar también mensajes en línea cerca de cada campo. Las personas con baja visión que amplían la pantalla pueden no ver la alerta a nivel de encabezado mientras están centradas en el área de entrada, y las personas que usan teclado deben recorrer una distancia considerable para leer el error.
Relación con la normativa de accesibilidad de Turquía
La Circular Presidencial 2025/10 de Turquía, publicada en el Boletín Oficial n.º 32933 el 21 de junio de 2025, establece requisitos obligatorios de accesibilidad web para una amplia gama de entidades que operan en Turquía. La circular adopta WCAG 2.2 como su estándar técnico, lo que hace que todos los criterios de éxito de Nivel A —incluido WCAG 3.3.1 Identificación de errores— sean legalmente obligatorios para las organizaciones cubiertas.
El calendario de cumplimiento establecido por la circular es de un año para las instituciones públicas y de dos años para las entidades del sector privado a partir de la fecha de publicación. Esto significa que las instituciones públicas deben lograr la conformidad con WCAG 2.2 Nivel A para junio de 2026, y las entidades cubiertas del sector privado para junio de 2027.
Las entidades cubiertas por la circular incluyen una amplia sección de los servicios digitales turcos. Las instituciones públicas, incluidos todos los ministerios del gobierno central, municipios, universidades estatales y organismos públicos, deben garantizar que sus servicios digitales sean accesibles. En el sector privado, la circular abarca plataformas de comercio electrónico, bancos e instituciones financieras, hospitales y proveedores de atención sanitaria privados, empresas de telecomunicaciones con 200,000 o más abonados, agencias de viajes, empresas de transporte privado y escuelas privadas autorizadas por el Ministerio de Educación Nacional (MoNE).
Para todas estas entidades, WCAG 3.3.1 es directamente relevante siempre que se utilicen formularios en línea, lo que en la práctica significa casi todos los puntos de contacto digitales. Los formularios de pago de comercio electrónico, los flujos de apertura de cuentas bancarias, los portales de registro de pacientes de hospitales, los formularios de solicitud de prestaciones gubernamentales, los sistemas de reserva de aerolíneas y autobuses, y las páginas de inscripción escolar dependen de la validación de formularios. Si cualquiera de estos sistemas detecta automáticamente un error de entrada y no identifica el campo ni describe el error en texto, está en violación directa de los requisitos de la circular.
El incumplimiento de la circular puede exponer a las entidades cubiertas a escrutinio regulatorio, riesgo reputacional y posibles sanciones a medida que madura el marco de aplicación de la accesibilidad digital en Turquía. Más allá del cumplimiento legal, la adhesión a 3.3.1 demuestra un compromiso con la prestación de servicios inclusivos, garantizando que todas las personas ciudadanas, incluidas aproximadamente 8,5 millones de personas con discapacidad en Turquía (según datos de TÜİK), puedan acceder a servicios esenciales en línea sin barreras. Las organizaciones que operan bajo el marco del SDK de Accsible deben priorizar tanto el cumplimiento estructural automatizado como las pruebas manuales exhaustivas para garantizar que su gestión de errores satisfaga plenamente este criterio fundamental.
Fuentes y referencias
- W3C Understanding 3.3.1 Error Identification
- W3C Techniques for 3.3.1 Error Identification
- WebAIM: Usable and Accessible Form Validation and Error Recovery
- MDN: aria-describedby attribute
- MDN: aria-invalid attribute
- MDN: aria-errormessage attribute
- Deque University: Using aria-describedby for form error messages
