HTML Forms

Formulários & Validação

Formulários são a maneira como os usuários enviam dados para o seu app. Labels, os tipos de input corretos e a validação nativa resolvem a maior parte do trabalho antes mesmo de você escrever qualquer JavaScript.

beginner14 min readUpdated 15 de set. de 2026
signup.html
html
<!-- signup.html -->
<form action="/signup" method="post">
  <label for="email">Email address</label>
  <input id="email" name="email" type="email"
         autocomplete="email" required />

  <label for="password">Password</label>
  <input id="password" name="password" type="password"
         minlength="8" required />

  <button type="submit">Create account</button>
</form>
Wrapper
elemento form
Atributo chave
name
Rotulagem
label com for
Tipos
email, tel, number, date
Validação
Restrições nativas

Por que importa

Por que formulários exigem atenção

Usável por todos

Labels adequados, agrupamento e mensagens de erro fazem com que os formulários funcionem com leitores de tela e teclados.

Validado duas vezes

A validação nativa melhora a experiência; a validação no servidor protege os dados.

O controle certo

Tipos de input corretos fornecem ao usuário o teclado adequado e habilitam verificações integradas.

O panorama completo

As três partes de um bom formulário

Um label claro, o tipo de controle correto e uma validação honesta que ajude em vez de bloquear.

Estrutura

Markup

form, label, input, fieldset e legend descrevem os dados que você coleta.

Rotulagem

Clareza

Cada controle precisa de um label associado a ele, tanto visível quanto programaticamente.

Validação

Guarda

Restrições nativas somadas a verificações no servidor mantêm dados ruins fora do sistema.

Formulários em resumo

O núcleo dos formulários

form e controles

O form envolve inputs, selects, textareas e botões.

Tipos de Input

email, tel, number, date, url e outros alteram o teclado e a validação.

Labels

Associe cada controle a um label usando for e id.

Fieldsets

Agrupe controles relacionados com fieldset e legend.

Restrições

required, minlength, pattern, min, max e step.

Erros

Explique o que está errado e como corrigir, próximo ao campo.

Uma breve historia

De inputs básicos a restrições avançadas

  1. 1993

    Os primeiros formulários

    Formulários HTML permitiram que páginas enviassem dados para um servidor.

    93
  2. 1999

    Controles do HTML4

    Um conjunto estável de inputs, selects e textareas torna-se padrão.

    99
  3. 2011

    Tipos de input do HTML5

    email, number, date, range e outros chegam com validação nativa.

    11
  4. 2014

    Constraint Validation API

    Scripts ganham acesso ao estado de validade e mensagens personalizadas.

    14
  5. Hoje

    Melhor UX por padrão

    Tipos e atributos corretos oferecem teclados móveis, preenchimento automático e verificações gratuitamente.

    Hoje

O guia completo

Formulários & Validação: Tudo que voce precisa saber

Por que formulários merecem atenção

Os formulários são onde os usuários pagam, se cadastram, pesquisam e enviam mensagens. Eles também são onde a frustração se concentra: um label ausente, um erro confuso ou um input que abre o teclado errado podem afastar um usuário em segundos.

A boa notícia é que o HTML já resolve a maior parte disso. Com labels adequados, os tipos de input corretos e restrições nativas, você consegue formulários acessíveis, amigáveis para dispositivos móveis e validados antes mesmo de escrever uma linha de JavaScript.

Estrutura do formulário

Um formulário envolve seus controles e declara onde e como enviá-los.

<!-- signup.html -->
<form action="/signup" method="post">
  <label for="email">Email address</label>
  <input id="email" name="email" type="email" autocomplete="email" required />

  <label for="password">Password</label>
  <input id="password" name="password" type="password" minlength="8" required />

  <button type="submit">Create account</button>
</form>
  • action é a URL que recebe os dados.
  • method é get ou post.
  • name em cada controle é a chave nos dados enviados.
  • type=“submit” dispara o envio; um botão simples dentro de um formulário assume o comportamento de submit por padrão, portanto, use type="button" para outras ações.

Labels

Todo controle precisa de um label. O label é anunciado por leitores de tela, serve como um alvo de clique maior e permanece visível após o campo ser preenchido.

<!-- label.html -->
<label for="phone">Phone number</label>
<input id="phone" name="phone" type="tel" autocomplete="tel" />

Você também pode envolver o controle dentro do label, o que os associa implicitamente:

<label>
  Subscribe to the newsletter
  <input type="checkbox" name="subscribe" />
</label>

Placeholders não são labels. Eles desaparecem assim que o usuário digita, geralmente possuem baixo contraste e não são anunciados de forma confiável. Use um label real e, se for útil, um hint.

Tipos de input

Escolher o type correto fornece aos usuários o teclado móvel adequado e habilita a validação nativa.

Tipo Use para Benefício
email Endereços de e-mail Teclado de e-mail, verificação de formato
tel Números de telefone Teclado numérico
number Valores numéricos Entrada numérica, min/max/step
url Endereços web Teclado de URL, verificação de formato
date Datas Seletor de data
password Segredos Entrada mascarada
search Campos de busca Teclado de busca, botão de limpar
file Uploads Seletor de arquivos e filtragem de tipo

Use autocomplete com tokens padrão como email, given-name, postal-code e new-password para que os navegadores e gerenciadores de senhas possam ajudar.

Agrupando controles

Agrupe controles relacionados para que a relação entre eles fique clara para todos.

<!-- address.html -->
<fieldset>
  <legend>Shipping address</legend>

  <label for="street">Street</label>
  <input id="street" name="street" autocomplete="address-line1" />

  <label for="city">City</label>
  <input id="city" name="city" autocomplete="address-level2" />
</fieldset>

fieldset e legend agrupam radio buttons e campos relacionados, que são anunciados pelos leitores de tela como um conjunto. Para grupos de radio buttons, use sempre um fieldset com um legend.

Validação nativa

O HTML oferece validação de restrições (constraint validation) por meio de atributos.

<!-- validate.html -->
<input type="email" name="email" required />
<input type="password" name="password" minlength="8" required />
<input type="number" name="age" min="18" max="120" step="1" />
<input type="text" name="handle" pattern="[a-z0-9_]{3,15}" />
<input type="url" name="website" />

O navegador bloqueia o envio e exibe uma mensagem quando uma restrição falha. Você pode estilizar esses estados com CSS:

/* styles.css */
input:invalid { border-color: #dc2626; }
input:valid { border-color: #16a34a; }
input:focus-visible { outline: 2px solid #2563eb; }

As mensagens nativas são funcionais, porém sucintas e não traduzidas. Para formulários importantes, forneça suas próprias mensagens claras utilizando a Constraint Validation API:

// validate.js
const email = document.querySelector("#email");

email.addEventListener("invalid", () => {
  email.setCustomValidity("");
  if (email.validity.valueMissing) {
    email.setCustomValidity("Please enter your email address.");
  } else if (email.validity.typeMismatch) {
    email.setCustomValidity("That does not look like an email address.");
  }
});

email.addEventListener("input", () => email.setCustomValidity(""));

Lembre-se de limpar a mensagem personalizada durante a digitação (input), caso contrário, o campo permanecerá inválido.

Erros acessíveis

A validação só é útil se os usuários entenderem o que deu errado.

  • Exiba uma mensagem de texto clara ao lado do campo, não apenas uma borda vermelha.
  • Associe a mensagem ao controle utilizando aria-describedby.
  • Marque o campo com aria-invalid="true".
  • Mova o foco para o primeiro campo inválido ao enviar o formulário.
  • Resuma os erros no topo em formulários longos.
<!-- error.html -->
<label for="email">Email address</label>
<input id="email" name="email" type="email" required
       aria-invalid="true" aria-describedby="email-error" />
<p id="email-error" class="error">Please enter a valid email address.</p>

Nunca dependa apenas da cor; combine-a com texto e um ícone.

Sempre valide no servidor

A validação no lado do cliente é um recurso de experiência do usuário, não um controle de segurança. Qualquer pessoa pode editar a página, desativar o JavaScript ou enviar uma requisição diretamente. O servidor deve validar tipos, comprimentos, formatos e permissões, e retornar erros claros que o cliente possa exibir. Consulte o guia de Web Security.

Melhores práticas

  • Atribua a cada controle um label visível e associado.
  • Use o tipo de input correto e tokens autocomplete.
  • Agrupe controles relacionados com fieldset e legend.
  • Prefira constraints nativas e, em seguida, aprimore-as com a Constraint Validation API.
  • Exiba mensagens de erro acessíveis e específicas próximas ao campo.
  • Valide novamente no servidor em cada requisição.
  • Mantenha os formulários curtos e solicite apenas o que for necessário.

Erros comuns

  • Usar placeholders em vez de labels.
  • Esquecer os atributos name, fazendo com que os campos não sejam enviados.
  • Enviar dados sensíveis via GET.
  • Confiar apenas na validação no client-side para segurança.
  • Comunicar erros apenas através de cores.
  • Resetar todo o formulário ao ocorrer um erro de validação, resultando na perda dos dados inseridos.

Próximos passos

Formulários combinam marcação, acessibilidade e validação. Reforce a marcação com Semantic HTML, torne-a inclusiva com o Guia de Acessibilidade e gerencie os envios com JavaScript. Depois, faça uma auditoria em um formulário do seu app utilizando o checklist acima.

Rotulando um input

Um label visível e associado é anunciado por leitores de tela e permanece quando o campo é preenchido. Um placeholder desaparece.

Preferir
<label for="email">Email address</label>
<input id="email" name="email"
       type="email" autocomplete="email" />
Evitar
<input name="email" type="email"
       placeholder="Email address" />

Validando input

Use o tipo nativo e as restrições, depois valide no servidor. Verificações apenas com JavaScript podem ser ignoradas por qualquer pessoa.

Preferir
<input type="email" name="email"
       required autocomplete="email" />
<input type="password" name="password"
       minlength="8" required />
Evitar
<input name="email" />
<input name="password" />
<!-- checked only after submit -->

Perguntas frequentes

Perguntas frequentes

Keep learning

Related topics from the roadmap.

$ comecar a aprender

Pronto para aprender Forms & Validation?

Nosso tutorial interativo te guia por Forms & Validation passo a passo — com quizzes e codigo real que voce pode executar no navegador.