Las cuatro prácticas de ingeniería que marcan la diferencia
Con criterio propio. No exhaustivas. Los patrones que, cuando se siguen, eliminan la mayoría de las regresiones de accesibilidad antes de la revisión de código.
HTML semántico primero, ARIA después
Cuando el HTML nativo puede hacer el trabajo, úselo. <button>
tiene integrados el manejo del teclado, el foco, el rol y la activación con
Enter/Space; <label> asocia un control con su descripción;
<dialog> incluye el comportamiento de trampa de foco e
inactivación del resto de la página que, de otro modo, habría que implementar
manualmente; <details> es un widget de revelación sin ningún
JavaScript. ARIA es la válvula de escape: útil cuando no existe ningún elemento
nativo para la tarea, perjudicial cuando se añade sobre uno que ya funciona.
Referencia: los
criterios de éxito de WCAG 2.2 y
la Guía de prácticas de autoría ARIA del W3C.
La compatibilidad con el teclado no es una casilla que marcar
Cada elemento interactivo debe funcionar solo con el teclado. Tab
y Shift+Tab para moverse; Enter o Space para activar; Esc para cerrar
una superficie transitoria (modal, popover, menú). El foco debe ser visible:
nunca outline: none; sin un sustituto. El foco debe
desplazarse de forma coherente: cuando se abre un modal, el foco entra en él;
cuando el modal se cierra, el foco regresa al elemento que lo abrió.
Pruebe con el teclado antes de probar con el ratón;
el ratón oculta errores que el teclado pone de manifiesto de inmediato.
Nombres y descripciones accesibles
No salpique de aria-label. El nombre accesible proviene
por defecto del contenido de texto del elemento; aria-labelledby
referencia el texto de otro nodo; aria-label reemplaza
todo con una cadena codificada en duro (y debe ser el último recurso,
porque omite la traducción y tiende a desincronizarse de la etiqueta
visible). La descripción accesible es distinta:
aria-describedby referencia el nodo de texto de ayuda o de
mensaje de error. Verifique en el árbol de accesibilidad de DevTools
qué recibe realmente el lector de pantalla: las suposiciones y la realidad
suelen discrepar.
Pruebe en su CI real, no solo en local
Una comprobación local con axe es una prueba de cordura. Un CI en verde
es una barrera contra regresiones. Conecte eslint-plugin-jsx-a11y
a cada PR; añada aserciones de axe-core a las pruebas
unitarias y e2e; ejecute flujos de AT-driver en páginas representativas
para que un lector de pantalla real participe. El
análisis de herramientas de prueba con lector de pantalla
detalla qué merece automatizarse y qué sigue requiriendo revisión manual.
La cadena de herramientas — 13 herramientas y bibliotecas seleccionadas
Cada entrada corresponde a una fase del ciclo de vida: lint, prueba unitaria, e2e, runtime, monitorización o revisión manual, para conectar la herramienta adecuada a la barrera adecuada.
-
Runtime
axe-core
El motor de pruebas de accesibilidad que impulsa la mayor parte de las herramientas que se listan a continuación. Intégrelo en pruebas unitarias, suites e2e o conéctelo al DOM en tiempo de desarrollo para comprobaciones en tiempo de ejecución.
-
E2E
axe DevTools
Extensión de navegador con integraciones para Playwright, Cypress, Jest y Selenium. La interfaz de usuario estándar orientada al desarrollador sobre axe-core.
-
Reglas de análisis estático (lint) para React JSX. Detecta los fallos más evidentes (alt ausente, roles inválidos, onClick sobre div) antes de la revisión de código.
-
Runtime
vue-axe
Comprobador de accesibilidad en tiempo de ejecución para Vue: muestra las infracciones de axe-core en la consola del navegador mientras se desarrolla.
-
Prueba unitaria
@testing-library/jest-dom
Matchers orientados a la accesibilidad para pruebas unitarias. Fomenta buscar nodos del modo en que lo haría un lector de pantalla (por rol + nombre accesible) en lugar de por clase.
-
Automatización de navegador de extremo a extremo con integración de primera clase de axe-core. Ejecute aserciones de accesibilidad en navegadores reales en CI.
github.com/dequelabs/axe-core-npm/tree/develop/packages/playwright ↗
-
Prueba unitaria
Storybook a11y addon
Análisis con axe-core a nivel de componente dentro de su sistema de diseño. Detecta infracciones antes de que lleguen al código de producción.
-
Monitorización
Pa11y
Escáner de línea de comandos que envuelve axe-core y HTML CodeSniffer. El primitivo adecuado para una barrera de CI que falla la compilación ante regresiones.
-
Monitorización
Lighthouse CI
Impulsado por Google, incluye una auditoría de accesibilidad (axe-core bajo el capó) más puntuaciones de rendimiento y buenas prácticas. Útil para el seguimiento de tendencias.
-
Manual
WebAIM WAVE
Escáner visual que superpone los problemas sobre la página en vivo. Adecuado para diseñadores y autores de contenido que prefieren no examinar un informe JSON.
-
Prueba unitaria
Wallaby + axe-core integration
Ciclo de retroalimentación en el IDE: ejecuta aserciones de axe-core junto al cursor del test. Acelera la iteración del desarrollador al conectar un nuevo componente.
-
Estándar incubado por el W3C para manejar lectores de pantalla reales desde pruebas automatizadas. La frontera de las pruebas de accesibilidad automatizadas: por fin se va más allá de las comprobaciones estáticas al estilo axe.
-
Manual
NVDA + JAWS + VoiceOver
Los lectores de pantalla que realmente usan sus usuarios. Ninguna automatización reemplaza la revisión manual con lector de pantalla para el 30–40 % de los problemas WCAG que la automatización no puede detectar.
Guías específicas por framework
Los problemas de accesibilidad que cambian de forma según el ecosistema, y la cobertura en profundidad de cada uno.
React
Claves en listas (las listas con claves incorrectas confunden a los lectores
de pantalla cuando los elementos se reordenan). Gestión del foco al cambiar
de ruta (sin ella, el foco permanece en el enlace que activó la navegación
y la nueva página es invisible para los usuarios de tecnologías de asistencia).
Portals y trampas de foco: un modal renderizado en document.body
sigue necesitando mantener el foco dentro de sí mismo. Las discrepancias de
hidratación que modifican la estructura del DOM entre SSR y cliente pueden
romper silenciosamente las relaciones ARIA. Nuestro análisis en profundidad
sobre regiones aria-live en frameworks modernos
aborda el patrón de anuncio de regiones en vivo que la reconciliación de
React tiende a romper.
Vue / Svelte / Solid
Patrones similares; los cambios de estado reactivo no disparan
actualizaciones de regiones en vivo por defecto. El modelo de reactividad
de cada framework tiene una definición diferente de «el DOM ha cambiado»,
y los lectores de pantalla perciben la actualización de nodo resultante,
o no, de formas sutilmente distintas. v-if frente a
v-show en Vue, las declaraciones reactivas de Svelte y
la reactividad de grano fino de Solid producen actualizaciones diferentes
en el árbol de accesibilidad para lo que parece el mismo código.
Móvil nativo (iOS + Android)
Una superficie de API completamente diferente. iOS expone UIAccessibility
(y .accessibilityLabel() /
.accessibilityHint() de SwiftUI) a VoiceOver; Android expone
AccessibilityNodeInfo a TalkBack. El ARIA de estilo web no se traduce. El
artículo sobre
APIs de accesibilidad nativas para móvil
mapea los conceptos web a sus equivalentes nativos para que los ingenieros
formados en web dejen de adivinar.
Bibliotecas de componentes
Las bibliotecas headless (Radix UI, Headless UI, React Aria) se encargan de las partes difíciles —gestión del foco, manejo del teclado, conexión de ARIA— y dejan el diseño visual completamente en sus manos. Las bibliotecas con funciones completas (Material UI, Chakra, Ant) incluyen opiniones visuales, pero varían enormemente en calidad de accesibilidad, y «accesible por defecto» raramente significa «auditado con lectores de pantalla reales». Nuestro análisis de bibliotecas de componentes accesibles evalúa las principales opciones frente a pruebas reales con tecnologías de asistencia.
Lista de verificación de accesibilidad para la revisión de PR
Imprímala, péguela en su plantilla de PR o intégrela en un bot. El mínimo que todo revisor debería comprobar.
- Los elementos interactivos funcionan solo con el teclado (Tab + Enter + Space + Esc).
- El indicador de foco es visible en cada elemento interactivo.
- Los campos de formulario tienen un
<label>asociado. - Los mensajes de error están asociados a sus campos (
aria-describedbyo texto adyacente). - Los cambios de contenido dinámico se anuncian mediante
aria-livecuando corresponde. - Los diálogos modales atrapan el foco y lo devuelven al elemento que los abrió al cerrarse.
- Las imágenes tienen texto alternativo significativo; las imágenes decorativas llevan
alt="". - Las listas usan
<ul>/<ol>/<dl>, no una ensalada de<div>. - La jerarquía de encabezados es coherente (sin niveles omitidos).
- Las pruebas de lint + axe pasan en CI antes de la fusión.
Antipatrones de ingeniería frecuentes
Los patrones que superan la revisión de código y luego fallan en producción. Detéctelos antes.
- El «widget overlay»: JavaScript de terceros que afirma añadir accesibilidad a un sitio existente. No lo hace, con frecuencia rompe la capa de tecnología de asistencia y ha generado su propia oleada de demandas. Contexto: los proveedores de overlays.
-
role="button"sobre un<div>: añade el anuncio del rol sin el comportamiento de teclado (Enter, Space) ni la participación en el orden de tabulación. Use<button>. -
aria-hidden="true"sobre elementos enfocables: crea una trampa de foco en la que los usuarios de teclado pueden tabular hasta un elemento que el lector de pantalla tiene instrucción de ignorar. Elimine el elemento del orden de tabulación contabindex="-1"o elimine elaria-hidden. - Lista desplegable personalizada sin manejo de teclado:
un combobox basado en
<div>que se abre al hacer clic pero ignora las teclas de flecha, Inicio/Fin, escritura anticipada y Esc. El análisis de bibliotecas de componentes accesibles recoge las bibliotecas que resuelven esto correctamente desde el primer momento. - Notificaciones toast que no se anuncian:
una superficie transitoria renderizada sin
role="status"(polite) orole="alert"(assertive). Los usuarios videntes la ven; los usuarios de lectores de pantalla, no. - DOM generado que rompe el árbol de accesibilidad:
los envoltorios pesados alrededor de un input (un select personalizado
construido con doce
<div>anidados) suelen ocultar el control real a las tecnologías de asistencia. Pruebe lo que ve la tecnología de asistencia, no solo lo que ve el usuario.
El kit de herramientas + pipeline de monitorización
La mayoría de los equipos necesitan tres cosas en secuencia: un análisis puntual cuando algo parece roto, una referencia de ingeniería cuando quieren comprender los patrones subyacentes, y una capa de monitorización continua una vez que la accesibilidad entra en la hoja de ruta de producción. Nuestro escáner gratuito WCAG 2.2 cubre lo primero: pegue una URL pública y obtenga un informe impulsado por axe en una nueva pestaña. La cobertura de ingeniería en el área editorial cubre lo segundo, incluidos análisis de la deuda de accesibilidad como deuda técnica y de incidentes de accesibilidad como postmortems de SRE para equipos que gestionan la accesibilidad a escala.
Para la capa continua, la guía de compra de herramientas de monitorización es la pieza más concreta del sitio. Evalúa axe Monitor, Siteimprove, Level Access y Qualibooth —el último integra la monitorización con el traspaso a una auditoría manual, la pieza que falta en la mayoría de los stacks solo automatizados— en función de la amplitud de cobertura, las tasas de falsos positivos y la limpieza con que los datos se integran en los flujos de trabajo de ingeniería. El objetivo de la monitorización es garantizar que las correcciones que se entregan hoy no regresen el próximo sprint.
Preguntas de ingeniería más frecuentes
Las preguntas que surgen en cada reunión inicial sobre accesibilidad. Reflejadas en los datos estructurados FAQPage.
- ¿Es
aria-labelmejor que las etiquetas de texto visibles? -
No. El texto visible es casi siempre mejor: beneficia a los usuarios
videntes, a los usuarios videntes con discapacidades cognitivas, a los
usuarios de control por voz (que dicen lo que ven) y a las herramientas
de traducción. Recurra a
aria-labelsolo cuando no haya texto visible que asociar (botones con solo icono) o cuando el texto visible realmente no sea el nombre accesible que se desea. - ¿Debo usar roles ARIA para todo?
-
No. La primera regla de ARIA es «no use ARIA». Los elementos HTML
nativos incluyen el rol correcto, el comportamiento de teclado correcto
y la semántica correcta en el árbol de accesibilidad. Use ARIA
cuando (y solo cuando) no exista ningún elemento nativo adecuado:
por ejemplo, una lista de pestañas, un árbol o un diálogo personalizado
en el que no se pueda usar
<dialog>. - ¿Cómo pruebo la accesibilidad en CI?
-
Tres capas, ordenadas por coste. (1) Lint:
eslint-plugin-jsx-a11yen cada PR. (2) Pruebas unitarias:@testing-library/jest-dommásjest-axe(o@axe-core/react) en cada componente. (3) Extremo a extremo:@axe-core/playwrighten recorridos de usuario representativos. Añada una barrera de Pa11y o Lighthouse CI en staging para detectar la deriva que las capas inferiores dejan pasar. - ¿Son axe-core y Lighthouse lo mismo?
- Lighthouse utiliza axe-core bajo el capó para su auditoría de accesibilidad, pero ejecuta un subconjunto seleccionado de las reglas y las presenta dentro de un informe más amplio de rendimiento / SEO / buenas prácticas. axe-core es el motor en sí: cuando se quiere el conjunto completo de reglas o se desea ampliarlo, se usa axe-core directamente. Para la mayoría de los equipos: use Lighthouse para el seguimiento de tendencias y axe-core para la barrera real.
- ¿Cuál es la configuración mínima de pruebas de accesibilidad para un proyecto React?
-
Añada
eslint-plugin-jsx-a11ya la configuración de ESLint existente (se incluye por defecto con create-react-app y Next.js). Añada@testing-library/jest-domyjest-axea la configuración de pruebas unitarias, y llame aexpect(await axe(container)).toHaveNoViolations()en al menos una prueba por componente. Ese es el mínimo: detecta aproximadamente el 40 % de los problemas WCAG reales con unas pocas horas de configuración. - ¿Es necesario probar con lectores de pantalla reales?
- Sí, para cualquier funcionalidad del producto que un usuario de tecnología de asistencia vaya a utilizar realmente. Las herramientas automatizadas detectan los fallos estructurales (etiquetas ausentes, contraste, discrepancias en roles), pero no los experienciales (foco que salta al pie de página, regiones en vivo que no anuncian, un modal «accesible» que atrapa el foco dentro del subárbol incorrecto). Planifique al menos una revisión manual por cada versión principal con NVDA en Windows y VoiceOver en macOS / iOS.
Próximos pasos
Ejecute una comprobación rápida con el escáner gratuito WCAG 2.2 si está haciendo el triaje de una página concreta. Lea el análisis de herramientas de prueba con lector de pantalla antes de integrar AT-driver en CI. Y si la accesibilidad está pasando de «auditoría puntual» a «preocupación continua en producción», la guía de compra de herramientas de monitorización es la pieza más concreta del sitio para elegir un proveedor.