Guía práctica para formularios accesibles
Todo el mundo tiene un algo que le da pereza cuando toca evaluar la accesibilidad, a mi, me da mucha pereza evaluar la accesibilidad de los carruseles pero lo siguiente que me da pereza son los formularios, porque os cuento un secreto, en muchas ocasiones no son formularios accesibles.
Los formularios son el cuello de botella de casi todas tus conversiones, puedes tener la campaña más inclusiva del mundo, el copy más inspirador y la propuesta de valor más clara, pero si tu formulario es un laberinto inaccesible, estás tirando el dinero.
Y lo peor es que muchas veces el problema no está en la cantidad de campos (aunque también), sino en detalles aparentemente insignificantes: etiquetas mal escritas, instrucciones invisibles y mensajes de error que parecen diseñados sin pensar en que la persona que lo está leyendo puede frustrarse al leer este mensaje.
La buena noticia es que arreglar esto no requiere rediseñar todo desde cero. La mala es que casi nadie lo hace bien, (a ver, esto es una de esas afirmaciones para crear polémica, pero hay mucha gente que lo hace bien), así que prepárate para detectar estos problemas en prácticamente todos los formularios con los que te cruces esta semana.
Por qué los formularios son el punto crítico de la accesibilidad
Un formulario es una conversación: tú haces una pregunta, el usuario responde, y si algo va mal, le explicas cómo arreglarlo, el problema es que muchos formularios parecen diseñados por gente que nunca ha tenido que rellenarlos con prisas, en un móvil pequeño, con poca luz, con manos ocupadas o usando un lector de pantalla.
Según distintos estudios sobre usabilidad y accesibilidad web, los formularios mal diseñados son una de las principales causas de abandono en procesos de conversión. Cuando añades barreras de accesibilidad a la ecuación (etiquetas que no se asocian correctamente con campos, instrucciones que desaparecen al hacer clic, errores genéricos tipo «campo inválido»), estás expulsando activamente a usuarios que ya habían llegado hasta ahí.
Las personas que usan lectores de pantalla, teclado en lugar de ratón, lupas de aumento o navegación por voz dependen especialmente de que cada campo esté correctamente etiquetado, de que las instrucciones sean claras y permanentes, y de que los errores se comuniquen de forma específica y constructiva.
Pero aquí viene la parte interesante: cuando arreglas estos problemas, mejoras la experiencia para todo el mundo, no solo para usuarios con necesidades específicas.
Etiquetas: el elemento más básico que todo el mundo hace mal
Una etiqueta es ese texto que te dice qué va en cada campo: «Nombre», «Email», «Teléfono», etc. Parece sencillo, pero hay mil formas de fastidiarlo.
El problema del placeholder como etiqueta
El clásico: poner solo un placeholder (ese texto gris dentro del campo) y ninguna etiqueta visible fuera.
No accesible:
<input type="email" placeholder="Tu email aquí...">
¿Qué pasa aquí?
- El contraste bajo del placeholder (ese gris clarito) puede ser ilegible para personas con baja visión o en pantallas con mucho reflejo (también incumple el Criterio 1.4.3 – Contraste mínimo – Nivel AA).
- Cuando haces clic y empiezas a escribir, el placeholder desaparece y ya no recuerdas qué te estaban pidiendo.
- Los lectores de pantalla a menudo no leen los placeholders como etiquetas, así que el usuario no sabe qué debe rellenar.
Accesible:
<label for="email">Email</label>
<input type="email" id="email" name="email" placeholder="nombre@empresa.com">
La solución es simple: usa una etiqueta visible y permanente fuera del campo. El placeholder puede quedarse como ayuda adicional (ejemplo: «nombre@empresa.com«), pero nunca debe sustituir a la etiqueta.
Etiquetas ambiguas o incompletas
Otro clásico: etiquetas tipo «Nombre» sin especificar si quieres nombre completo, solo nombre de pila, nombre y apellidos, o nombre legal.
No accesible:
<label for="nombre">Nombre</label>
<input type="text" id="nombre">
Accesible:
<label for="nombre-completo">Nombre completo</label>
<input type="text" id="nombre-completo" name="nombre-completo" placeholder="Juan García López">
O si necesitas separar:
<label for="nombre">Nombre</label>
<input type="text" id="nombre" name="nombre">
<label for="apellidos">Apellidos</label>
<input type="text" id="apellidos" name="apellidos">
Investigaciones sobre usabilidad de formularios indican que las etiquetas claras y específicas reducen significativamente los errores de entrada y el tiempo de completado. Si necesitas un dato concreto (CIF, DNI, código postal), dilo claramente en la etiqueta, no lo escondas en un tooltip o en un mensaje de error que aparecerá después.
Asociación técnica entre etiqueta y campo
Esto es la parte técnica (no os preocupéis, es poco): en HTML, las etiquetas deben estar asociadas correctamente con sus campos mediante el atributo for y el id correspondiente.
No Accesible:
<div>Email</div>
<input type="email" name="email">
Accesible:
<label for="email-usuario">Email</label>
<input type="email" id="email-usuario" name="email">
Esto permite que:
- Los lectores de pantalla anuncien la etiqueta cuando el campo recibe el foco.
- Puedas hacer clic en la etiqueta para activar el campo (especialmente útil en checkboxes y radios).
Ejemplo con checkbox
No accesible:
<input type="checkbox" name="newsletter">
<span>Quiero recibir la newsletter</span>
Accesible:
<input type="checkbox" id="newsletter" name="newsletter">
<label for="newsletter">Quiero recibir la newsletter</label>
Si tu formulario no hace esto, técnicamente funciona visualmente, pero es invisible o confuso para tecnologías de apoyo. Y esto no es un «nice to have»: las Pautas WCAG 2.1 lo consideran un requisito de nivel A, el más básico.
Instrucciones: información que debe estar siempre visible
Las instrucciones son esas indicaciones extra tipo «Introduce tu teléfono sin espacios ni guiones» o «La contraseña debe tener al menos 8 caracteres, una mayúscula y un número». El problema es que muchas veces estas instrucciones:
- Aparecen solo en un tooltip que se activa al pasar el ratón (inútil en móvil y para usuarios de teclado).
- Están escritas en un tamaño de letra microscópico.
- Desaparecen cuando el campo recibe el foco.
- Solo aparecen después de que cometes el error (demasiado tarde).
Instrucciones preventivas, no reactivas
Decirle al usuario antes de que rellene el campo qué formato necesitas es mucho más eficiente que esperarte a que se equivoque.
No accesible (instrucción solo en title):
<label for="telefono">Teléfono</label>
<input type="tel" id="telefono" title="Introduce tu teléfono sin espacios">
Problema: el atributo title solo aparece al hover y no es anunciado por todos los lectores de pantalla.
No accesible (instrucción oculta):
<label for="telefono">Teléfono</label>
<input type="tel" id="telefono">
<span class="tooltip">Introduce 9 dígitos sin espacios</span>
<!-- tooltip solo visible al hover -->
Problema: la información crítica no está disponible en móviles ni para usuarios de teclado.
Accesible:
<label for="telefono">Teléfono</label>
<input type="tel" id="telefono" name="telefono" aria-describedby="telefono-ayuda">
<small id="telefono-ayuda">Introduce 9 dígitos sin espacios (ejemplo: 612345678)</small>
Estudios sobre experiencia de usuario en formularios demuestran que mostrar requisitos de forma preventiva reduce errores y mejora la tasa de completado.
Si tu campo de teléfono solo acepta números españoles, dilo. Si el CIF debe empezar por una letra, avisa. Si la contraseña tiene requisitos específicos, muéstralos antes, no después de tres intentos fallidos.
Ejemplo con contraseña:
Accesible:
<label for="password">Contraseña</label>
<input type="password" id="password" name="password" aria-describedby="password-requisitos">
<div id="password-requisitos">
<p>Tu contraseña debe contener:</p>
<ul>
<li>Al menos 8 caracteres</li>
<li>Una letra mayúscula</li>
<li>Un número</li>
<li>Un carácter especial (!@#$%)</li>
</ul>
</div>
Dónde colocar las instrucciones
Las mejores opciones:
- Justo debajo de la etiqueta, antes del campo.
- Justo debajo del campo, en un tamaño legible.
- Asociadas técnicamente al campo mediante
aria-describedbypara que los lectores de pantalla las anuncien.
Lo que NO funciona:
- Tooltips que solo aparecen al hover.
- Textos en gris clarito prácticamente invisible (incumple Criterio 1.4.3 – Contraste mínimo – Nivel AA).
- Información crítica escondida en un enlace «¿Qué es esto?».
Mensajes de error: el momento de la verdad
Aquí es donde se separan los formularios decentes de los que te dan ganas de cerrar la pestaña y buscar otra empresa.
Un buen mensaje de error debe ser:
- Específico: no «campo inválido», sino «el email debe incluir una @».
- Constructivo: explica qué está mal y cómo arreglarlo.
- Visible: no te obligues a buscar un texto rojo minúsculo perdido en la pantalla.
- Accesible: anunciado por lectores de pantalla y asociado técnicamente con el campo.
Errores genéricos: el antipatrón más común
No accesible:
<label for="telefono">Teléfono</label>
<input type="tel" id="telefono" class="error">
<span style="color: red;">Campo inválido</span>
Problemas:
- «Campo inválido» no explica nada (incumple Criterio 3.3.1 y 3.3.3).
- Solo usa color para indicar error (incumple Criterio 1.4.1 – Uso del color – Nivel A).
- No está asociado técnicamente con el campo (incumple Criterio 4.1.2 – Nombre, función, valor – Nivel A).
Accesible:
<label for="telefono">Teléfono</label>
<input type="tel" id="telefono" aria-invalid="true" aria-describedby="telefono-error">
<span id="telefono-error" class="error-message" role="alert">
<span aria-hidden="true">⚠️</span>
El teléfono debe tener 9 dígitos sin espacios (ejemplo: 612345678)
</span>
Investigaciones sobre fricción en formularios señalan que los mensajes de error vagos son una de las principales causas de abandono, especialmente para usuarios con discapacidad cognitiva o que usan tecnologías de apoyo.
Indicadores visuales múltiples
No te fíes solo del color rojo para indicar un error. Algunas personas no distinguen bien los colores, otras tienen pantallas configuradas en escala de grises, y los lectores de pantalla obviamente no «ven» el rojo.
Usa múltiples indicadores:
- Color (rojo/verde) + icono (✗ / ✓) + texto explicativo.
- Borde del campo más grueso o con patrón distinto.
- Mensaje de error asociado técnicamente al campo mediante ‘aria-describedby’.
Campos obligatorios: márcalos bien (o mejor aún, redúcelos)
Si un campo es obligatorio, debe estar claro ANTES de que el usuario intente enviar el formulario. El asterisco (*) es una convención extendida, pero:
- Debe ir acompañado de una leyenda al principio del formulario tipo «* campos obligatorios».
- No confíes solo en el color o el asterisco: usa también la palabra «obligatorio» en la etiqueta o en el atributo ‘aria-required’.
Pero seamos honestos: la mejor estrategia es reducir los campos obligatorios al mínimo indispensable. Análisis de optimización de conversiones muestran que cada campo adicional reduce significativamente la tasa de completado. Si no lo necesitas AHORA, no lo pidas.
Checklist rápida para auditar tus formularios
Antes de publicar (o arreglar) tu próximo formulario, pregúntate:
- Etiquetas:
- ¿Cada campo tiene una etiqueta visible y permanente?
- ¿Las etiquetas están asociadas técnicamente con sus campos?
- ¿Son claras y específicas sobre qué información pides?
- Instrucciones:
- ¿Las instrucciones están visibles antes de que el usuario empiece a rellenar?
- ¿Son legibles (tamaño, contraste)?
- ¿Están asociadas técnicamente con el campo?
- Errores:
- ¿Los mensajes de error son específicos y constructivos?
- ¿Usas múltiples indicadores (color + icono + texto)?
- ¿Los errores se anuncian correctamente a lectores de pantalla?
- ¿Validas en el momento adecuado (no demasiado pronto)?
- Campos obligatorios:
- ¿Están claramente marcados desde el principio?
- ¿Son realmente todos necesarios?
- Navegación por teclado:
- ¿Se puede completar todo el formulario sin ratón?
- ¿El orden de tabulación tiene sentido?
- ¿Los estados de foco son visibles?
En resumen, los formularios son ese punto del embudo donde tu discurso inclusivo se encuentra con la realidad técnica. Puedes hablar todo lo que quieras sobre diversidad y accesibilidad en tu campaña, pero si luego tu formulario de contacto es inaccesible, te estás contradiciendo en el momento que más importa: cuando el usuario está a punto de convertir.
La buena noticia es que no necesitas ser desarrollador experto para auditar y mejorar esto. Con un poco de atención a etiquetas claras, instrucciones preventivas y mensajes de error útiles, puedes hacer que tus formularios dejen de ser una barrera y se conviertan en lo que deberían ser: una conversación clara, respetuosa y eficiente con tus usuarios.
Y si alguien te dice que «eso es muy técnico» o «no es prioridad», recuérdale que cada usuario que abandona un formulario por barreras de accesibilidad es dinero que se va por el desagüe, y que arreglar esto cuesta infinitamente menos que seguir pagando tráfico que se pierde en el último paso.

