accessibility

Coloca etiqueta em cada campo de formulário

O MetricSpot verifica em cada campo de formulário se existe um <label> associado, aria-label ou aria-labelledby. Campos sem etiqueta são anunciados pelos leitores de ecrã apenas como "editar texto".

O que esta verificação faz

Percorre cada <input>, <textarea> e <select> da página e confirma que cada um tem um nome acessível através de uma das seguintes vias:

  • Um <label for="id"> explícito.
  • Um <label>…<input>…</label> envolvente.
  • Um atributo aria-label="…".
  • Um aria-labelledby="other-id" a apontar para texto visível.
  • Um atributo title (o pior — uma tooltip de hover é um fallback inferior, mas conta).

A verificação falha quando um campo não tem nenhum destes e não é um campo oculto, botão de submissão ou token csrf.

Porque é importante

Quem usa leitor de ecrã a preencher um formulário de checkout ouve “editar texto, editar texto, editar texto” em vez de “número do cartão, validade, CVV”. Campos sem etiqueta são inutilizáveis.

  • Impacto na conversão, não apenas conformidade. Todos os estudos de UX em formulários de pagamento mostram o mesmo: etiquetas visíveis (não apenas placeholders) aumentam a taxa de conclusão em 10–20%. Os placeholders desaparecem assim que começas a escrever — o utilizador deixa de poder confirmar o que está a digitar.
  • Exposição legal. As etiquetas de formulário estão entre as falhas WCAG mais citadas em processos de acessibilidade, porque são fáceis de verificar (abrir a página no NVDA, navegar por tab). A maioria das queixas ADA Title III contra sites de e-commerce nos EUA cita as etiquetas de formulário entre as três violações principais.
  • O preenchimento automático funciona melhor. Browsers e gestores de palavras-passe usam o texto da etiqueta para detetar o tipo de campo. Um campo “Email” com etiqueta é preenchido automaticamente com o email; um <input type="text"> sem etiqueta não é.

Como corrigir

Usa um <label> visível ligado ao campo por for/id. Não dependas apenas do placeholder.

O padrão canónico:

<label for="email">Endereço de email</label>
<input id="email" name="email" type="email" autocomplete="email" required>

Padrão envolvente (label como pai, sem for):

<label>
  Endereço de email
  <input name="email" type="email" autocomplete="email" required>
</label>

Botões só com ícone (sem texto visível) — usa aria-label:

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

React com inputs controlados:

<label htmlFor="email">Endereço de email</label>
<input
  id="email"
  type="email"
  value={email}
  onChange={(e) => setEmail(e.target.value)}
  autoComplete="email"
  required
/>

(Nota: o JSX usa htmlFor, não forfor é palavra reservada.)

Etiquetas flutuantes (Material Design, shadcn/ui) — a etiqueta visível é animada, mas o HTML por baixo continua a precisar de emparelhar <label for> com <input id>. Se o teu design system esconde visualmente a etiqueta, usa class="sr-only" (utilitário Tailwind) em vez de eliminar o elemento:

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

Evita.

  • Não uses o placeholder como única etiqueta — desaparece ao começar a escrever e tem contraste menor.
  • Não uses <div> ou <span> como etiqueta — não expõem a associação à tecnologia de assistência.
  • Não reutilizes o mesmo id em vários campos — a associação quebra silenciosamente.

Linters e CI. O eslint-plugin-jsx-a11y inclui uma regra label-has-associated-control. Adiciona-a à configuração e falha o CI quando faltarem etiquetas. axe-core / Playwright apanham-nas em runtime — vê o snippet na página Pontuação de acessibilidade Lighthouse.

Perguntas frequentes

O placeholder é uma etiqueta?

Não. Os placeholders são dicas para campos vazios; desaparecem em foco. As WCAG declaram explicitamente que os placeholders não satisfazem o requisito de etiquetas.

E o aria-label?

aria-label funciona, mas etiquetas visíveis funcionam melhor — utilizadores com deficiências cognitivas, utilizadores com baixa visão a usar lupas e quem traduz a página no browser beneficiam todos de texto que possam ver. Usa aria-label apenas quando uma etiqueta visível seria redundante (botões só com ícone, campos de pesquisa com ícone de submissão claro).

Preciso de etiqueta para botões de submissão?

<button type="submit">Criar conta</button> já tem o seu próprio texto visível — esse é o nome acessível, não é necessária etiqueta adicional. O mesmo para <input type="submit" value="Criar conta">. Botões de submissão só com ícone precisam de aria-label.

Fontes

Última atualização 2026-05-11