Kit de herramientas · Para desarrolladores

Accesibilidad web para desarrolladores — diseñada para ingenieros que prefieren corregir la causa raíz antes que añadir un overlay

La sección del sitio orientada a la ingeniería. Patrones de HTML semántico, roles ARIA que funcionan realmente en producción, entornos de pruebas compatibles con lectores de pantalla, recetas de integración en CI y el estado del arte por framework en el manejo del teclado.

Concebido como punto de entrada: los patrones, las herramientas, los entornos de prueba y las guías específicas por framework que los ingenieros necesitan realmente para entregar funcionalidades accesibles sin teatro de overlays. Con enlaces al escáner gratuito WCAG 2.2 para el triaje puntual y a la guía de compra de herramientas de monitorización para la cobertura continua.

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.

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-describedby o texto adyacente).
  • Los cambios de contenido dinámico se anuncian mediante aria-live cuando 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 con tabindex="-1" o elimine el aria-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) o role="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-label mejor 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-label solo 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-a11y en cada PR. (2) Pruebas unitarias: @testing-library/jest-dom más jest-axe (o @axe-core/react) en cada componente. (3) Extremo a extremo: @axe-core/playwright en 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-a11y a la configuración de ESLint existente (se incluye por defecto con create-react-app y Next.js). Añada @testing-library/jest-dom y jest-axe a la configuración de pruebas unitarias, y llame a expect(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.