accessibility

Etiqueta cada input del formulario

MetricSpot comprueba que cada input de formulario tenga un <label> asociado, aria-label o aria-labelledby. Sin etiqueta, el lector solo dice "editar texto".

Qué comprueba esta auditoría

Recorre cada <input>, <textarea> y <select> de la página y verifica que tenga un nombre accesible a partir de una de estas fuentes:

  • Un <label for="id"> explícito.
  • Un <label>…<input>…</label> que envuelve el input.
  • Un atributo aria-label="…".
  • Un aria-labelledby="other-id" apuntando a un texto visible.
  • Un atributo title (lo peor: un tooltip al pasar el ratón es un sustituto inferior, pero cuenta).

La comprobación falla cuando el input no tiene ninguno de estos y no es un campo oculto, un botón submit o un token csrf.

Por qué importa

Un usuario de lector de pantalla rellenando un checkout oye “editar texto, editar texto, editar texto” en lugar de “número de tarjeta, caducidad, CVV”. Los campos sin etiqueta son inservibles.

  • Impacto en conversión, no solo en accesibilidad. Todos los estudios de UX sobre formularios de pago muestran lo mismo: las etiquetas visibles (no solo placeholders) suben la tasa de completado entre un 10% y un 20%. El placeholder desaparece en cuanto empiezas a escribir: el usuario no puede comprobar lo que está tecleando.
  • Exposición legal. Las etiquetas de formulario son uno de los fallos WCAG más citados en demandas de accesibilidad porque son fáciles de verificar (abre la página en NVDA, navega con Tab). La mayoría de denuncias bajo el Título III de la ADA contra ecommerce estadounidenses citan las etiquetas de formulario entre las tres violaciones principales.
  • El autocompletado funciona mejor. Los navegadores y gestores de contraseñas usan el texto de la etiqueta para detectar el tipo de campo. Un campo “Email” etiquetado se autocompleta con el email; un <input type="text"> sin etiqueta, no.

Cómo solucionarlo

Usa un <label> visible conectado al input mediante for/id. No te fíes solo del placeholder.

El patrón canónico:

<label for="email">Correo electrónico</label>
<input id="email" name="email" type="email" autocomplete="email" required>

Patrón envolvente (el label como padre, sin necesidad de for):

<label>
  Correo electrónico
  <input name="email" type="email" autocomplete="email" required>
</label>

Botones solo con icono (sin texto visible) — usa aria-label:

<button type="submit" aria-label="Buscar">
  <svg aria-hidden="true">…</svg>
</button>

React con inputs controlados:

<label htmlFor="email">Correo electrónico</label>
<input
  id="email"
  type="email"
  value={email}
  onChange={(e) => setEmail(e.target.value)}
  autoComplete="email"
  required
/>

(Nota: en JSX se usa htmlFor, no forfor es una palabra reservada.)

Floating labels (Material Design, shadcn/ui) — la etiqueta visible está animada, pero el HTML subyacente debe seguir emparejando <label for> con <input id>. Si tu sistema de diseño oculta la etiqueta visualmente, usa class="sr-only" (utilidad de Tailwind) en lugar de eliminar el elemento:

<label for="search" class="sr-only">Buscar en los docs</label>
<input id="search" type="search" placeholder="Buscar…">

Lo que no hay que hacer.

  • No uses el placeholder como única etiqueta: desaparece al empezar a escribir y tiene menos contraste.
  • No uses <div> ni <span> como label: no exponen la asociación a la tecnología asistiva.
  • No reutilices el mismo id en varios inputs: la asociación se rompe en silencio.

Linters y CI. eslint-plugin-jsx-a11y trae la regla label-has-associated-control. Añádela a tu configuración y haz que CI falle ante etiquetas ausentes. axe-core / Playwright las detectan en tiempo de ejecución: mira el snippet de la página Puntuación de accesibilidad de Lighthouse.

Preguntas frecuentes

¿Es placeholder una etiqueta?

No. Los placeholders son pistas para campos vacíos; desaparecen al enfocar. WCAG dice explícitamente que el placeholder no satisface el requisito de etiquetado.

¿Y aria-label?

aria-label funciona, pero las etiquetas visibles funcionan mejor: los usuarios con discapacidades cognitivas que ven la pantalla, los de baja visión con lupa y los que traducen la página en el navegador se benefician de un texto que pueden ver. Usa aria-label solo cuando una etiqueta visible sería redundante (botones solo con icono, inputs de búsqueda con un icono de envío claro).

¿Necesito etiqueta para los botones submit?

<button type="submit">Registrarme</button> tiene su propio texto visible: ese es el nombre accesible, no hace falta etiqueta extra. Lo mismo para <input type="submit" value="Registrarme">. Los botones submit solo con icono sí necesitan aria-label.

Fuentes

Última actualización 2026-05-11