accessibility

Etichetta ogni campo del form

MetricSpot controlla che ogni campo del form abbia un <label> associato, un aria-label o un aria-labelledby. I campi senza etichetta vengono annunciati come "edit text" dagli screen reader.

Cosa controlla questo check

Scorre ogni <input>, <textarea> e <select> della pagina e verifica che ognuno abbia un nome accessibile da una di queste fonti:

  • Un <label for="id"> esplicito
  • Un <label>…<input>…</label> che avvolge il campo
  • Un attributo aria-label="…"
  • Un aria-labelledby="other-id" che punta a un testo visibile
  • Un attributo title (il peggiore — un tooltip al passaggio del mouse è un fallback inferiore, ma conta)

Il check fallisce quando un input non ha nessuna di queste e non è un campo nascosto, un pulsante submit o un token csrf.

Perché è importante

Un utente di screen reader che compila un form di checkout sente “edit text, edit text, edit text” invece di “numero carta, scadenza, CVV”. I campi senza etichetta sono inutilizzabili.

  • Impatto sulla conversione, non solo conformità. Ogni studio UX sui form di pagamento mostra la stessa cosa: le label di campo visibili (non solo placeholder) alzano i tassi di completamento del 10–20%. I placeholder spariscono appena inizi a digitare — il tuo utente non può ricontrollare cosa sta scrivendo.
  • Esposizione legale. Le label dei form sono una delle violazioni WCAG più citate nei contenziosi sull’accessibilità perché sono facili da verificare (apri la pagina con NVDA, premi tab nei campi). La maggior parte delle denunce ADA Title III contro siti ecommerce statunitensi cita le label di form fra le prime tre violazioni.
  • L’autofill funziona meglio. Browser e password manager usano il testo della label per riconoscere il tipo di campo. Un campo “Email” etichettato riceve l’autofill dell’email; un <input type="text"> senza etichetta no.

Come risolvere

Usa una <label> visibile collegata all’input tramite for/id. Non affidarti al solo placeholder.

Il pattern canonico:

<label for="email">Email address</label>
<input id="email" name="email" type="email" autocomplete="email" required>

Pattern con wrapping (label come genitore, niente for):

<label>
  Email address
  <input name="email" type="email" autocomplete="email" required>
</label>

Pulsanti con sola icona (senza testo visibile) — usa aria-label:

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

React con input controllati:

<label htmlFor="email">Email address</label>
<input
  id="email"
  type="email"
  value={email}
  onChange={(e) => setEmail(e.target.value)}
  autoComplete="email"
  required
/>

(Nota: JSX usa htmlFor, non forfor è una parola riservata.)

Label fluttuanti (Material Design, shadcn/ui) — la label visibile è animata, ma l’HTML sottostante deve comunque accoppiare <label for> con <input id>. Se il design system nasconde visualmente la label, usa class="sr-only" (un’utility Tailwind) invece di togliere l’elemento:

<label for="search" class="sr-only">Search the docs</label>
<input id="search" type="search" placeholder="Search…">

Da evitare.

  • Non usare il placeholder come unica label — sparisce appena inizi a digitare e ha contrasto più basso.
  • Non usare <div> o <span> come label — non espongono l’associazione alla tecnologia assistiva.
  • Non riutilizzare lo stesso id su più input — l’associazione si rompe in silenzio.

Linter e CI. eslint-plugin-jsx-a11y include una regola label-has-associated-control. Aggiungila alla config e fai fallire la CI sulle label mancanti. axe-core / Playwright possono individuarle a runtime — vedi lo snippet sulla pagina Punteggio accessibilità Lighthouse.

Domande frequenti

Il placeholder è una label?

No. I placeholder sono suggerimenti per i campi vuoti; svaniscono al focus. WCAG dichiara esplicitamente che i placeholder non soddisfano il requisito delle label.

E aria-label?

aria-label funziona, ma le label visibili funzionano meglio — utenti vedenti con disabilità cognitive, utenti ipovedenti con ingranditori e utenti che traducono la pagina nel browser beneficiano tutti di un testo che possono vedere. Usa aria-label solo quando una label visibile sarebbe ridondante (pulsanti con sola icona, campi di ricerca con un’icona di submit chiara).

Serve una label per i pulsanti submit?

<button type="submit">Sign up</button> ha già il proprio testo visibile — quello è il nome accessibile, non serve una label extra. Lo stesso per <input type="submit" value="Sign up">. I pulsanti submit con sola icona richiedono aria-label.

Fonti

Ultimo aggiornamento 2026-05-11