Programação Por Equipe DevBras

Capa do artigo: Placeholder não é rótulo: o campo precisa dizer o que pergunta depois de preenchido

Placeholder não é rótulo: o campo precisa dizer o que pergunta depois de preenchido

Ligue o rótulo ao campo, use placeholder só como exemplo, ponha instruções em texto de ajuda com aria-describedby e faça rótulo flutuante sem perder acessibilidade.

No cadastro de fornecedor, os campos diziam "Razão social", "CNPJ" e "E-mail do financeiro", tudo em cinza dentro da caixa. A atendente preencheu, foi revisar antes de salvar e encontrou dois e-mails. Qual era o do financeiro e qual era o comercial? A pergunta tinha sumido junto com a dica.

A resposta curta: todo campo precisa de um rótulo visível, fora da caixa, ligado a ele por label for. O placeholder é opcional e serve só para mostrar um exemplo de formato, como "00.000.000/0000-00". Instrução importante vai num texto de ajuda abaixo do campo, ligado com aria-describedby, e não dentro da caixa.

Por que o placeholder não funciona como rótulo

O placeholder desaparece no primeiro caractere digitado. Isso causa quatro problemas, todos concretos.

  • Memória: quem volta ao campo para revisar não sabe mais o que ele perguntava. Em formulários longos, ou quando o preenchimento automático completa tudo de uma vez, isso acontece o tempo todo.
  • Contraste: o placeholder costuma ser cinza claro para "parecer dica", e fica difícil de ler. Se você aumenta o contraste, ele passa a parecer um valor já preenchido, e a pessoa pula o campo.
  • Nome acessível: leitores de tela até leem o placeholder quando não há rótulo, mas o suporte varia, e ferramentas de controle por voz dependem de um nome visível para a pessoa dizer "clicar em CNPJ".
  • Erro: quando o campo é marcado como inválido, o usuário vê a mensagem de erro e o próprio valor, mas não a pergunta original.

Existe uma versão antiga desse problema, a "marca d'água" feita com JavaScript que acabava gravada no banco como se fosse dado. Se o seu sistema ainda tem isso, o post marca d'água no campo mostra como migrar e limpar os registros. Aqui o foco é o formulário novo, feito certo desde o início.

Como montar o campo certo

  1. Escreva o rótulo como pergunta curta ou substantivo: "E-mail do financeiro". Fica acima do campo, sempre visível.
  2. Ligue o rótulo ao campo com for apontando para o id do input. Clicar no rótulo passa a focar o campo, o que também aumenta a área de toque.
  3. Coloque instruções (formato, para que serve, se é opcional) num parágrafo abaixo do rótulo ou do campo, com id próprio.
  4. Ligue esse texto ao campo com aria-describedby, para o leitor de tela ler a ajuda junto com o nome.
  5. Se usar placeholder, que seja exemplo e comece com "Ex.:", para não parecer valor preenchido nem instrução.
  6. Quando houver erro, acrescente a mensagem ao aria-describedby, sem trocar o rótulo.
<label for="cnpj">CNPJ</label>
<p id="cnpj-ajuda">Só números ou com pontuação, como aparece no cartão CNPJ.</p>
<input id="cnpj" name="cnpj" inputmode="numeric"
       aria-describedby="cnpj-ajuda" placeholder="Ex.: 12.345.678/0001-90">

<label for="email-fin">E-mail do financeiro</label>
<p id="email-fin-ajuda">Para onde enviamos boletos e notas fiscais.</p>
<input id="email-fin" name="email_financeiro" type="email" autocomplete="email"
       aria-describedby="email-fin-ajuda">

Com erro, o campo ganha a mensagem sem perder nada:

<input id="email-fin" name="email_financeiro" type="email" autocomplete="email"
       aria-describedby="email-fin-ajuda email-fin-erro" aria-invalid="true">
<p id="email-fin-erro">Falta o domínio. Exemplo: financeiro@empresa.com.br</p>

O leitor de tela anuncia algo como "E-mail do financeiro, campo de edição, inválido, Para onde enviamos boletos e notas fiscais. Falta o domínio". A ordem exata varia entre leitores, mas nome, ajuda e erro chegam juntos. Onde e como mostrar o erro está detalhado em onde colocar o erro para ninguém perder.

Rótulo flutuante sem cair na armadilha

O design pede o visual "Material", em que o nome começa dentro da caixa e sobe quando a pessoa digita. Dá para fazer, desde que o texto que sobe seja um label de verdade, não o placeholder. O truque é usar um placeholder de um espaço só e o seletor :placeholder-shown para saber se o campo está vazio.

<div class="campo-flutuante">
  <input id="razao" name="razao_social" placeholder=" " autocomplete="organization">
  <label for="razao">Razão social</label>
</div>
.campo-flutuante {
  position: relative;
}
.campo-flutuante input {
  width: 100%;
  padding: 1.5rem 0.75rem 0.5rem;
  font-size: max(16px, 1rem);
}
.campo-flutuante label {
  position: absolute;
  left: 0.75rem;
  top: 1rem;
  color: #444;
  pointer-events: none;
  transition: top 0.15s, font-size 0.15s;
}
.campo-flutuante input:focus + label,
.campo-flutuante input:not(:placeholder-shown) + label {
  top: 0.35rem;
  font-size: 0.75rem;
}

Três cuidados. O rótulo reduzido ainda precisa ter contraste de texto normal, nada de cinza fantasma. A área de cima do campo precisa de espaço suficiente para o rótulo pequeno não sobrepor o valor. E o preenchimento automático do navegador às vezes completa o campo sem disparar a mudança visual em todos os navegadores, então teste com o gerenciador de senhas e o autopreenchimento de endereço ligados. Se o rótulo ficar por cima do valor preenchido, a versão simples, com rótulo fixo acima, é mais segura.

Como conferir o que o navegador entendeu

Abra as ferramentas de desenvolvedor, selecione o campo e procure o painel de acessibilidade. Ele mostra o "nome" calculado para o elemento. Esse nome deve ser igual ao rótulo visível, ou começar com ele. Se aparecer vazio, ou vier do placeholder, o campo está sem rótulo de verdade. O mesmo painel mostra a descrição, que deve trazer o texto de ajuda.

O teste humano é mais simples ainda: preencha o formulário inteiro com o autopreenchimento, tire uma captura de tela e mostre a alguém que não viu o formulário vazio. Cada valor tem um nome ao lado? A arrumação geral do formulário, com rótulo em cima e uma coluna só, está em formulário que não cansa, e os tokens de preenchimento automático em autocomplete que ajuda.

Erros comuns

  • Placeholder como único nome do campo. Depois de preenchido, ninguém sabe o que o campo perguntava, nem quem revisa nem quem corrige um erro.
  • Rótulo visível sem for ligado ao id. O leitor de tela anuncia "campo de edição" sem nome, e clicar no texto não foca o campo.
  • Instrução importante dentro do placeholder. "Mínimo 8 caracteres, com um número" some no primeiro caractere, quando a pessoa mais precisava ler.
  • Placeholder com cara de valor. "contato@empresa.com" em cor escura faz a pessoa achar que o campo já está preenchido e pular.
  • Rótulo flutuante feito com o próprio placeholder. O texto que sobe é decorativo, e o campo continua sem nome acessível.
  • Trocar o rótulo pela mensagem de erro. O campo passa a se chamar "Campo obrigatório" e a pergunta original desaparece.

Checklist

  • Todo campo tem label visível com for igual ao id do input.
  • O nome acessível de cada campo, no painel do navegador, bate com o rótulo visível.
  • Instruções estão em texto de ajuda ligado por aria-describedby.
  • Placeholder, quando existe, é um exemplo e começa com "Ex.:".
  • Rótulo e placeholder têm contraste legível.
  • Mensagens de erro somam ao rótulo, não o substituem.
  • O formulário preenchido continua compreensível numa captura de tela.

Preencha agora o formulário mais longo do seu sistema com o autopreenchimento do navegador e olhe para ele sem clicar em nada. Você ainda sabe, campo por campo, o que cada um perguntava?

Avalie este artigo

Referência: https://www.w3.org/WAI/tutorials/forms/labels/