Saltar al contenido

Para quienes desarrollan webs

Una web sin accesibilidad no está terminada

Si entregás un sitio que no se puede usar con teclado o con un lector de pantalla, entregaste un sitio a medias. La buena noticia: la mayoría de los problemas se evitan con decisiones que ya tomás todos los días. Este es el criterio que uso antes de dar un proyecto por terminado.

Por Mapa Bianchi · Basado en WCAG 2.2, nivel AA

Tres correcciones que resuelven muchísimo

Lo que más veo

<div class="btn" onclick="enviar()">
  Enviar
</div>

Cómo lo resuelvo

<button type="button" onclick="enviar()">
  Enviar
</button>
El button ya es enfocable, se activa con Enter y Espacio y se anuncia como botón. El div no hace nada de eso.

Lo que más veo

<input type="email"
  placeholder="Tu email">

Cómo lo resuelvo

<label for="email">Tu email</label>
<input id="email" type="email"
  autocomplete="email">
El placeholder desaparece al escribir y no siempre se anuncia. El label asociado le da nombre al campo para siempre.

Lo que más veo

*:focus {
  outline: none;
}

Cómo lo resuelvo

:focus-visible {
  outline: 3px solid #B45309;
  outline-offset: 2px;
}
:focus-visible muestra el anillo solo cuando se navega con teclado, así no molesta a quien usa mouse y nadie se queda a oscuras.

El criterio, área por área

1. Estructura y semántica

El HTML bien elegido hace la mitad del trabajo: los lectores de pantalla navegan por títulos, regiones y enlaces.

  • Un solo h1 por página y títulos que no saltan niveles.
  • Regiones con header, nav, main y footer.
  • lang declarado en el html.
  • Un <title> distinto para cada página.
  • Botones para acciones, enlaces para navegar. Nunca un div con onClick.

2. Teclado y foco

Si no se puede usar con teclado, no se puede usar con un switch, con un lector de pantalla ni con un control por voz.

  • Todo lo interactivo se alcanza y se activa con Tab, Enter y Espacio.
  • El orden del foco sigue el orden visual.
  • El foco se ve siempre, con al menos 3:1 de contraste. Nada de outline: none sin reemplazo.
  • Hay un enlace para saltar al contenido.
  • Los menús y modales se cierran con Escape y devuelven el foco a donde estaba.

3. Formularios

Es donde más gente abandona. Y casi siempre se resuelve con atributos que ya existen.

  • Cada campo tiene un label asociado. El placeholder no es una etiqueta.
  • Los errores se explican con texto, no solo con un borde rojo, y se vinculan al campo con aria-describedby.
  • autocomplete en nombre, email, teléfono y dirección.
  • Los grupos de opciones van en fieldset con legend.

4. Imágenes, íconos y medios

Todo lo que no es texto necesita una alternativa, y lo decorativo tiene que poder ignorarse.

  • Las imágenes informativas tienen alt con sentido; las decorativas, alt="".
  • Los botones de solo ícono tienen nombre accesible.
  • Los SVG decorativos llevan aria-hidden="true".
  • Los videos tienen subtítulos y nada se reproduce solo con sonido.

5. Color, tamaño y movimiento

Lo visual también es estructura: si falla, mucha gente no llega al contenido.

  • Texto con contraste de 4,5:1 (3:1 si es grande). Íconos y bordes de campos, 3:1.
  • El color nunca es la única forma de transmitir información.
  • La página funciona con zoom al 200 % y a 320 px de ancho sin scroll horizontal.
  • Las áreas táctiles miden al menos 24 × 24 px.
  • Se respeta prefers-reduced-motion.

6. Si es una SPA (React, Vue, Next…)

El navegador ya no anuncia los cambios de página: eso pasa a ser responsabilidad tuya.

  • El <title> se actualiza en cada ruta.
  • Al navegar, el foco va al título principal o al contenido.
  • Los resultados que aparecen sin recargar se anuncian con aria-live.
  • Las URLs internas funcionan al entrar directo o al recargar.

Cómo lo pruebo antes de entregar

  1. Automático: axe DevTools o Lighthouse en cada plantilla. Detectan una parte de los problemas (alrededor de un tercio), pero los detectan rápido.
  2. Teclado: desenchufo el mouse y recorro el flujo principal de punta a punta.
  3. Lector de pantalla: VoiceOver en Mac o iPhone, NVDA en Windows, TalkBack en Android. Con escuchar los títulos y los formularios ya aparecen muchos problemas.
  4. Zoom y celular: 200 % de zoom y 320 px de ancho.

En el caso de estudio cuento cómo apliqué este proceso a este mismo sitio y qué encontré.

Para aprender las reglas sin agotarte

Leer las WCAG o la especificación de ARIA de corrido cansa a cualquiera. Por eso armé dos referencias visuales para consultar cuando las necesitás.

Antes de sumar ARIA: la primera regla es no usarla si existe un elemento HTML que ya hace lo que necesitás. Un button real siempre es mejor que un div con role="button". ARIA mal usada empeora la experiencia en lugar de mejorarla.

Checklist de entrega

Marcá lo que ya cumple tu proyecto. El resumen se puede copiar para pegarlo en un pull request o mandárselo a tu cliente.

Estructura y semántica
Teclado y foco
Formularios
Imágenes, íconos y medios
Color, tamaño y movimiento
Si es una SPA (React, Vue, Next…)

0 de 27 puntos cumplidos

Ver lo que falta (27)
  • Un solo h1 por página y títulos que no saltan niveles.
  • Regiones con header, nav, main y footer.
  • lang declarado en el html.
  • Un <title> distinto para cada página.
  • Botones para acciones, enlaces para navegar. Nunca un div con onClick.
  • Todo lo interactivo se alcanza y se activa con Tab, Enter y Espacio.
  • El orden del foco sigue el orden visual.
  • El foco se ve siempre, con al menos 3:1 de contraste. Nada de outline: none sin reemplazo.
  • Hay un enlace para saltar al contenido.
  • Los menús y modales se cierran con Escape y devuelven el foco a donde estaba.
  • Cada campo tiene un label asociado. El placeholder no es una etiqueta.
  • Los errores se explican con texto, no solo con un borde rojo, y se vinculan al campo con aria-describedby.
  • autocomplete en nombre, email, teléfono y dirección.
  • Los grupos de opciones van en fieldset con legend.
  • Las imágenes informativas tienen alt con sentido; las decorativas, alt="".
  • Los botones de solo ícono tienen nombre accesible.
  • Los SVG decorativos llevan aria-hidden="true".
  • Los videos tienen subtítulos y nada se reproduce solo con sonido.
  • Texto con contraste de 4,5:1 (3:1 si es grande). Íconos y bordes de campos, 3:1.
  • El color nunca es la única forma de transmitir información.
  • La página funciona con zoom al 200 % y a 320 px de ancho sin scroll horizontal.
  • Las áreas táctiles miden al menos 24 × 24 px.
  • Se respeta prefers-reduced-motion.
  • El <title> se actualiza en cada ruta.
  • Al navegar, el foco va al título principal o al contenido.
  • Los resultados que aparecen sin recargar se anuncian con aria-live.
  • Las URLs internas funcionan al entrar directo o al recargar.

¿Querés que audite tu web antes de entregarla?

Reviso sitios y productos digitales con este criterio, y te devuelvo los hallazgos priorizados y con la solución.

Conocé mi consultoría en accesibilidad (en mapabianchi.online, se abre en otra pestaña)