Criterios de éxito de las WCAG · Level AA

WCAG 4.1.3: Mensajes de estado

Las WCAG 4.1.3 requieren que los mensajes de estado —como confirmaciones de envío de formularios, notificaciones de error y actualizaciones del carrito— sean determinables mediante programación a través de un rol o propiedad, de modo que las tecnologías de asistencia puedan anunciarlos sin exigir que la persona usuaria cambie el foco. Esto garantiza que las personas que dependen de lectores de pantalla reciban comentarios importantes incluso cuando el foco no se desplaza al mensaje.

Qué Significa Esta Regla

El Criterio de Éxito 4.1.3 Mensajes de Estado de las WCAG (Nivel AA, introducido en WCAG 2.1 y mantenido en WCAG 2.2) establece: «En contenido implementado usando lenguajes de marcado, los mensajes de estado pueden determinarse mediante programación a través de roles o propiedades de forma que puedan presentarse a la persona usuaria mediante tecnologías de apoyo sin recibir el foco.»

En términos prácticos, esto significa que siempre que tu interfaz produzca un mensaje para informar a la persona usuaria de un resultado — una búsqueda que devuelve resultados, un envío de formulario correcto, un artículo añadido a un carrito de compra, un error tras la validación o la finalización de un proceso — ese mensaje debe exponerse a la tecnología de apoyo (AT) de forma que no requiera que la persona usuaria navegue hasta él. La restricción clave es que el mensaje no debe depender de recibir el foco del teclado o el foco programático para ser anunciado.

El criterio se aplica a cualquier contenido escrito en un lenguaje de marcado (HTML, SVG, etc.) y abarca cuatro categorías amplias de mensajes de estado reconocidas por las WCAG:

  • Mensajes de éxito: confirmaciones como «Your order has been placed» o «Settings saved successfully.»
  • Mensajes de error o advertencia: retroalimentación de validación como «Email address is not valid» o «Please complete all required fields.»
  • Actualizaciones de progreso o estado: mensajes como «Loading… please wait» o «Upload 60% complete.»
  • Mensajes de cambio de contexto: actualizaciones dinámicas como «5 results found» o «3 items in your cart.»

Un mensaje cumple este criterio cuando se le asigna un rol o propiedad de región viva ARIA apropiado — más comúnmente role="status", role="alert", aria-live="polite" o aria-live="assertive" — de modo que los lectores de pantalla lo anuncien automáticamente cuando aparece o cambia, sin que la persona usuaria tenga que desplazarse hasta él con la tecla Tab.

Un mensaje no cumple cuando se inyecta dinámicamente en el DOM (mediante JavaScript) pero no tiene semántica de región viva, dejando a las personas usuarias de lectores de pantalla sin saber que algo ha cambiado en la página.

Una excepción importante definida por las WCAG: si un mensaje de estado se presenta moviendo el foco al elemento del mensaje (por ejemplo, un cuadro de diálogo que recibe el foco, o un cuadro de diálogo alert()), el criterio no se aplica a esa interacción — el propio movimiento del foco satisface la necesidad. El criterio se refiere específicamente a mensajes que aparecen sin un cambio de foco.

Por Qué Es Importante

Las personas usuarias de lectores de pantalla navegan por las páginas de forma lineal o saltando entre regiones, encabezados y controles interactivos. Cuando una página inyecta silenciosamente un banner «Your message has been sent» en el DOM sin anunciarlo, una persona ciega no tiene forma de saber que la acción tuvo éxito. Puede enviar el formulario de nuevo, esperar indefinidamente o simplemente abandonar la tarea confundida. El mismo problema afecta a personas con baja visión que dependen del zoom y la ampliación: un mensaje de estado que aparece fuera de su área de visualización actual pasa desapercibido a menos que se anuncie de forma audible.

Las personas con discapacidad motora que dependen de acceso por pulsador o tecnología de seguimiento ocular se ven igualmente afectadas. A menudo no pueden escanear rápidamente una página en busca de contenido nuevo; dependen de la AT para que les lleve la información relevante. Sin anuncios de regiones vivas, cada actualización de estado se convierte en un problema de aguja en un pajar.

Las personas con diversidad cognitiva también se benefician: una retroalimentación clara e inmediata confirma que una acción se ha completado y reduce la carga cognitiva de la incertidumbre. Cuando la AT anuncia «Item added to cart», una persona con discapacidad cognitiva no necesita buscar visualmente la confirmación antes de continuar.

Un escenario concreto del mundo real: una persona ciega está rellenando una solicitud de seguro con varios campos en el sitio web de un banco turco. Envía el formulario, pero se activa la validación del lado del cliente y se muestran cinco mensajes de error en rojo cerca de los campos. Como no hay ninguna región viva, el lector de pantalla de la persona (JAWS o NVDA) permanece en silencio. La persona asume que el formulario se envió correctamente y cierra la pestaña del navegador, perdiendo toda su solicitud. Con un role="alert" correctamente implementado o una región viva de resumen, la AT habría anunciado inmediatamente «3 errors found. Please review the highlighted fields», permitiendo a la persona corregir los problemas.

Desde la perspectiva empresarial, una retroalimentación de estado inaccesible perjudica directamente las tasas de conversión. Aproximadamente 1,3 mil millones de personas en todo el mundo viven con algún tipo de discapacidad, y garantizar que los mensajes de estado sean accesibles reduce el abandono de formularios, el volumen de tickets de soporte y el riesgo legal asociado al incumplimiento. Para las organizaciones turcas, la inaccesibilidad también puede constituir una violación de la Ley de Discapacidad nº 5378 y de las nuevas obligaciones del Decreto Presidencial descritas más adelante en este artículo.

Reglas Relacionadas de Axe-core

  • aria-live (automatizada): La regla aria-live de axe-core comprueba que los elementos que usan el atributo aria-live tengan asignado uno de los valores válidos: off, polite o assertive. Señala los elementos en los que aria-live está configurado con un valor no válido o mal escrito (por ejemplo, aria-live="true" o aria-live="yes"), lo que haría que la región viva fuera ignorada silenciosamente por la tecnología de apoyo. Esta regla garantiza que, cuando las personas desarrolladoras pretendan crear una región viva, el atributo esté correctamente formado para que los lectores de pantalla realmente lo respeten.
  • Pruebas manuales (necesarias para una cobertura completa): Las herramientas automatizadas no pueden auditar completamente la WCAG 4.1.3 porque el modo principal de fallo es una región viva ausente en un mensaje generado dinámicamente, una ausencia que el análisis estático de código tiene dificultades para detectar de forma fiable. Una herramienta que escanea el DOM antes de una interacción de la persona usuaria no puede saber qué elementos se convertirán más tarde en mensajes de estado. Axe-core puede no señalar un <div> que recibirá texto inyectado después de hacer clic en un botón, porque en el momento del escaneo el div está vacío o aún no existe. Por lo tanto, las pruebas manuales con un lector de pantalla en funcionamiento son esenciales: una persona probadora debe desencadenar el mensaje de estado y escuchar un anuncio. Si no se anuncia nada y el foco no se ha movido, el criterio no se cumple independientemente de lo que informen las herramientas automatizadas.

Cómo Probar

  1. Escaneo automatizado con axe DevTools o Lighthouse: Instala la extensión de navegador axe DevTools (Chrome o Firefox) y ejecuta un escaneo de página completa. Busca cualquier infracción bajo la regla aria-live. Comprueba también los problemas señalados por un uso incorrecto de aria-roledescription o aria-atomic. Recuerda que un escaneo automatizado limpio no significa que se cumpla 4.1.3; solo significa que no se encontraron atributos de región viva mal formados. Anota todos los elementos señalados y resuélvelos antes de pasar a los pasos manuales.
  2. Identificar todos los mensajes de estado dinámicos: Revisa la página y su JavaScript para catalogar todas las interacciones de la persona usuaria que producen un mensaje de estado sin recarga de página ni cambio de foco. Ejemplos comunes incluyen: retroalimentación de envío de formularios, insignias de cantidad en el carrito, recuentos de resultados de búsqueda, progreso de carga de archivos, confirmaciones de suscripción a boletines, actualizaciones de resultados de filtros y avisos de caducidad de sesión.
  3. Prueba manual con NVDA + Firefox: Abre la página con NVDA en ejecución. Activa cada mensaje de estado catalogado (envía un formulario, añade un artículo a un carrito, ejecuta una búsqueda). Escucha con atención: NVDA debería anunciar el texto del mensaje automáticamente en uno o dos segundos. Si no oyes nada y el foco no se ha movido, el criterio no se cumple. Usa el Visor de voz de NVDA (Herramientas > Visor de voz) para ver un registro de texto de todos los anuncios y comprobar su exactitud.
  4. Prueba manual con JAWS + Chrome: Repite las mismas interacciones con JAWS. Confirma que los mensajes con role="status" se anuncian con una interrupción educada y que los mensajes con role="alert" interrumpen inmediatamente. Comprueba que JAWS no anuncie el mismo mensaje varias veces debido a una configuración incorrecta de aria-atomic o aria-relevant.
  5. Prueba manual con VoiceOver + Safari (macOS/iOS): Usa VoiceOver en macOS con Safari y repite las mismas interacciones. Ten en cuenta que el manejo de aria-live por parte de VoiceOver puede diferir ligeramente del de los lectores de pantalla de Windows; confirma que se produzcan los anuncios y que estén redactados de forma coherente.
  6. Inspeccionar el DOM tras la interacción: Usando las DevTools del navegador, activa el mensaje de estado y luego inspecciona el elemento que apareció. Confirma que tiene role="status", role="alert" o un atributo aria-live válido. Si el mensaje se inyecta como texto plano en un contenedor sin marcar, no cumple. Comprueba también que el contenedor de la región viva existía en el DOM antes de que se inyectara el mensaje: los lectores de pantalla solo anuncian cambios en regiones vivas preexistentes, no en elementos insertados de nuevo en el DOM.

Cómo Corregir

Resumen de Validación de Formulario — Incorrecto

<!-- Error summary injected after failed submission -->
<div id='error-summary' class='error-box'>
  <p>Please fix the following errors before submitting:</p>
  <ul>
    <li>Email address is required.</li>
    <li>Password must be at least 8 characters.</li>
  </ul>
</div>
<!-- Problem: no role or aria-live attribute; screen readers will not announce this -->

Resumen de Validación de Formulario — Correcto

<!-- role="alert" causes immediate announcement when content is injected -->
<div id='error-summary' role='alert' class='error-box'>
  <p>Please fix the following errors before submitting:</p>
  <ul>
    <li>Email address is required.</li>
    <li>Password must be at least 8 characters.</li>
  </ul>
</div>
<!-- The container must be present in the DOM before JavaScript injects content into it -->

Recuento de Artículos en el Carrito de Compra — Incorrecto

<!-- Cart badge updated via JavaScript after user clicks "Add to cart" -->
<button id='add-to-cart'>Add to Cart</button>
<span id='cart-count' class='badge'>0</span>
<!-- Problem: cart-count has no live region; update from 0 to 1 is silent to screen readers -->

Recuento de Artículos en el Carrito de Compra — Correcto

<!-- Separate polite live region announces cart update without interrupting the user -->
<button id='add-to-cart'>Add to Cart</button>
<span id='cart-count' class='badge' aria-hidden='true'>1</span>

<!-- Visually hidden live region provides the announcement -->
<div
  id='cart-status'
  role='status'
  aria-live='polite'
  aria-atomic='true'
  class='visually-hidden'
>
  <!-- JavaScript updates this text: "1 item in your cart" -->
</div>
<!-- aria-atomic="true" ensures the full sentence is read, not just the changed number -->

Recuento de Resultados de Búsqueda — Incorrecto

<!-- Results count rendered after AJAX search -->
<p id='results-info'>Showing 24 of 140 results for "laptop"</p>
<!-- Problem: element is replaced entirely via innerHTML; no live region present -->

Recuento de Resultados de Búsqueda — Correcto

<!-- Live region pre-exists in the DOM; JavaScript updates its content after search -->
<p
  id='results-info'
  role='status'
  aria-live='polite'
  aria-atomic='true'
>
  Showing 24 of 140 results for "laptop"
</p>
<!-- role="status" implies polite + atomic; explicit attributes added for clarity and compatibility -->

Progreso de Carga de Archivo — Incorrecto

<!-- Progress percentage injected into DOM during upload -->
<div class='progress-container'>
  <div class='progress-bar' style='width: 60%'></div>
  <span id='progress-text'>60%</span>
</div>
<!-- Problem: percentage updates are visual only; no announcement to AT -->

Progreso de Carga de Archivo — Correcto

<!-- Use aria-valuenow on a progressbar role, plus a separate polite status for milestones -->
<div class='progress-container'>
  <div
    role='progressbar'
    aria-valuenow='60'
    aria-valuemin='0'
    aria-valuemax='100'
    aria-label='File upload progress'
    class='progress-bar'
    style='width: 60%'
  >
  </div>
</div>
<div
  id='upload-status'
  role='status'
  aria-live='polite'
  aria-atomic='true'
  class='visually-hidden'
>
  Upload complete. Your file has been saved.
</div>
<!-- Only announce key milestones (25%, 50%, 75%, complete) to avoid over-announcement -->

Errores Comunes

  • Crear el elemento de región viva al mismo tiempo que el mensaje: Añadir role="alert" a un elemento del DOM recién creado y rellenarlo inmediatamente a menudo fallará porque los lectores de pantalla aún no han registrado el nuevo nodo como región viva. Renderiza siempre el contenedor vacío al cargar la página y solo actualiza su contenido de texto cuando el mensaje de estado esté listo.
  • Usar aria-live="assertive" para mensajes no urgentes: Las regiones vivas de tipo assertive interrumpen lo que el lector de pantalla esté leyendo. Usar assertive para mensajes rutinarios como «Item added to cart» frustrará a las personas usuarias al cortar constantemente su flujo de lectura. Reserva assertive (o role="alert") para errores o advertencias realmente sensibles al tiempo; usa polite para todo lo demás.
  • Configurar aria-live con un valor no válido como "true" o "1": Solo "off", "polite" y "assertive" son valores válidos. Los valores no válidos desactivan silenciosamente la región viva sin advertencia del navegador, lo que hace que la regla aria-live de axe-core señale el elemento.
  • Confiar únicamente en el color o los iconos para comunicar el estado: Un icono de marca de verificación verde o un borde rojo inyectado en la página es una señal solo visual. Sin texto acompañante en una región viva, las personas usuarias de lectores de pantalla no reciben ninguna información. Empareja siempre los indicadores visuales con un anuncio basado en texto en una región viva.
  • Omitir aria-atomic="true" al actualizar parte de una frase: Si JavaScript actualiza solo un número dentro de una frase (por ejemplo, cambiar «3» a «4» en «4 items in cart»), algunos lectores de pantalla solo anunciarán el nodo cambiado, diciendo «4» sin contexto. Configurar aria-atomic="true" en el contenedor indica a la AT que lea toda la región como una unidad.
  • Anunciar cada actualización incremental de progreso: Inyectar un nuevo mensaje de estado cada segundo durante la carga de un archivo («10%», «11%», «12%»…) satura a la persona usuaria con anuncios y hace que el lector de pantalla sea inutilizable. Anuncia solo hitos significativos o el estado final de finalización.
  • Colocar el contenedor de la región viva dentro de elementos que se ocultan condicionalmente con display:none o visibility:hidden: Una región viva dentro de un elemento padre oculto es inerte y no anunciará nada, incluso si el propio elemento de la región viva es visible. Asegúrate de que la cadena de ancestros de la región viva no esté oculta en el momento del anuncio.
  • Usar role="alert" para mensajes de éxito que aparecen tras la navegación: Cuando un mensaje de estado persiste a través de una recarga de página (por ejemplo, un mensaje flash renderizado del lado del servidor tras una redirección), usar role="alert" puede provocar anuncios duplicados o excesivamente agresivos. Considera usar role="status" o mover el foco a la región del mensaje en su lugar, de modo que el anuncio se integre de forma natural en la navegación de la persona usuaria.
  • Suponer que las bibliotecas de tooltips o toasts gestionan automáticamente las regiones vivas: Muchas bibliotecas populares de componentes de interfaz (por ejemplo, Bootstrap Toasts, sistemas de tooltips personalizados) no añaden atributos de región viva ARIA por defecto. Inspecciona siempre el HTML renderizado de los componentes de terceros y añade role="status" o aria-live cuando falten.
  • No probar con lectores de pantalla reales antes de la publicación: Las herramientas automatizadas como axe no pueden detectar una región viva ausente en un mensaje de estado dinámico. Confiar solo en auditorías automatizadas dejará fallos de 4.1.3 sin detectar. Haz que las pruebas manuales con lectores de pantalla — con NVDA, JAWS y VoiceOver — sean una parte estándar de tu proceso de QA para cualquier funcionalidad que genere retroalimentación dinámica.

Relación con la Normativa de Accesibilidad de Turquía

La Circular Presidencial nº 2025/10 de Turquía, publicada en el Boletín Oficial nº 32933 el 21 de junio de 2025, establece obligaciones vinculantes de accesibilidad digital para una amplia gama de organizaciones que operan en Turquía. La Circular hace referencia a WCAG 2.1 y WCAG 2.2 como el estándar técnico para el cumplimiento y exige específicamente la conformidad de Nivel AA como base para la mayoría de las entidades cubiertas.

WCAG 4.1.3 Mensajes de Estado es un criterio de Nivel AA, lo que significa que entra directamente en el ámbito obligatorio de la Circular para todas las entidades cubiertas. Los siguientes tipos de organizaciones están explícitamente cubiertos:

  • Instituciones y organismos públicos: todos los organismos gubernamentales centrales y locales, ministerios, municipios y empresas estatales deben cumplir la conformidad AA en todos sus servicios digitales.
  • Bancos e instituciones financieras: regulados por la Agencia de Regulación y Supervisión Bancaria (BDDK), estas entidades ofrecen servicios en línea críticos (banca por internet, solicitudes de préstamos, gestión de tarjetas) donde la retroalimentación dinámica de estado — como confirmaciones de transacciones, mensajes de error y actualizaciones de saldo — es extremadamente común. Los fallos en 4.1.3 obstaculizan directamente la independencia financiera de las personas usuarias con discapacidad.
  • Plataformas de comercio electrónico: el comercio minorista en línea es un caso de uso principal para los mensajes de estado (actualizaciones del carrito, confirmaciones de pedidos, alertas de existencias). Las empresas de comercio electrónico deben garantizar que estas notificaciones dinámicas sean accesibles para todas las personas usuarias.
  • Hospitales e instituciones de salud: los sistemas de reserva de citas, portales de resultados de pruebas y paneles de pacientes utilizan con frecuencia mensajes de estado. La información de salud inaccesible puede tener consecuencias graves para las personas pacientes con discapacidad.
  • Empresas de telecomunicaciones con 200,000 o más abonados: los portales de gestión de cuentas, las notificaciones de facturación y las actualizaciones del estado del servicio deben cumplir todos el Nivel AA, incluido 4.1.3.
  • Agencias de viajes y empresas de transporte privado: las confirmaciones de reservas, la retroalimentación de selección de asientos y los mensajes de actualización de itinerarios son fundamentales para la experiencia de la persona usuaria y deben ser determinables mediante programación.
  • Colegios privados e instituciones educativas autorizadas por el Ministerio de Educación Nacional (MoNE): los sistemas de gestión del aprendizaje, portales de calificaciones y plataformas de matriculación deben exponer los mensajes de estado de forma accesible para atender a todo el alumnado y a sus familias.

El Logotipo de Accesibilidad (Erişilebilirlik Logosu), emitido por el Ministerio de Familia y Servicios Sociales, es la marca oficial de certificación para sitios web y aplicaciones turcas digitalmente accesibles. Para ser elegible para el Logotipo, una organización debe demostrar una conformidad completa de Nivel AA, que incluye 4.1.3. Dado que los mensajes de estado son omnipresentes en las interfaces web modernas, cualquier organización que busque el Erişilebilirlik Logosu debe tratar 4.1.3 como un elemento de auditoría obligatorio e implementar patrones de regiones vivas de forma coherente en todas las áreas de contenido dinámico.

Las organizaciones que no cumplan se arriesgan a acciones administrativas en virtud de la Circular, a la pérdida de elegibilidad para el Logotipo de Accesibilidad y a daños reputacionales en un mercado cada vez más consciente de la accesibilidad. Implementar correctamente WCAG 4.1.3 no es simplemente una casilla técnica que marcar: es una inversión concreta en el acceso digital en igualdad de condiciones para los aproximadamente 8,5 millones de ciudadanos de Turquía que viven con discapacidad.