Formulários HTML: os blocos básicos para criar formulários

Aprende o essencial dos formulários HTML. Cria formulários acessíveis com boa estrutura, tipos de campo, validação e tratamento da submissão.

Rascunho

Quando crias um formulário, usas frameworks ou criadores de formulários. Mas por baixo, todos usam formulários HTML. Se perceberes como funcionam os formulários HTML, percebes tudo o resto. Não dependes de nenhuma ferramenta nem framework. Conheces os fundamentos.

Este artigo cobre o elemento de formulário HTML, os tipos de campo, as etiquetas, a validação e como os formulários são realmente submetidos. Sem frameworks. Sem bibliotecas. Apenas HTML e os princípios em que tudo o resto assenta.

O elemento de formulário HTML

Um formulário é um elemento HTML que envolve os campos e envia os dados para algum lado. A estrutura básica é:

<form action="/submit" method="POST">

<input type="text" name="email">

<button type="submit">Send</button>

</form>

Três atributos importam. O atributo action diz ao formulário para onde enviar os dados. "/submit" significa enviar por POST para o endpoint /submit do teu servidor. Se o action estiver em branco, o formulário submete para a página atual. O atributo method diz ao formulário como viajam os dados. O POST envia os dados no corpo do pedido (seguro, escondido do URL). O GET acrescenta os dados ao URL (inseguro para dados sensíveis, útil para pesquisas). O atributo enctype só é necessário para carregamentos de ficheiros. Define enctype="multipart/form-data" quando o teu formulário tem um campo de ficheiro.

Tudo o que está dentro das etiquetas do formulário faz parte da submissão. Quando o utilizador clica no botão de submeter, o navegador recolhe todos os campos com nome e envia-os para o URL do action usando o método indicado.

Tipos de campo e o que fazem

text

<input type="text" name="first_name">

Um campo de texto de uma linha. O navegador mostra uma caixa de texto simples. Sem validação. Qualquer caractere é permitido.

email

<input type="email" name="email">

Um campo para endereços de email. No computador, parece um campo de texto. No telemóvel, o navegador mostra um teclado de email. Ao submeter, o navegador verifica se o valor parece um email (contém um @). Apenas validação básica.

password

<input type="password" name="password">

Texto que fica escondido como pontos ou asteriscos enquanto escreves. O valor continua a ser transmitido em texto simples, por isso usa sempre HTTPS em formulários com campos de palavra-passe.

number

<input type="number" name="age">

No computador, um campo de texto que só aceita números. No telemóvel, o navegador mostra um teclado numérico. O navegador impede a introdução de valores não numéricos.

date

<input type="date" name="birth_date">

Um seletor de datas. Em navegadores e dispositivos compatíveis, clicar no campo abre um calendário. O valor é formatado como YYYY-MM-DD.

checkbox

<input type="checkbox" name="agree" value="yes">

Uma caixa que liga e desliga. Se estiver marcada, o valor do campo é enviado ao submeter. Se não estiver marcada, o campo não é enviado de todo.

radio

<input type="radio" name="plan" value="starter"> Starter

<input type="radio" name="plan" value="pro"> Pro

Vários botões de opção com o mesmo name funcionam como um grupo. Só um pode estar selecionado de cada vez. O valor do selecionado é enviado ao submeter.

select (lista pendente)

<select name="country">

<option value="us">United States</option>

<option value="ca">Canada</option>

</select>

Um menu pendente. O valor da opção selecionada é enviado ao submeter.

textarea

<textarea name="message"></textarea>

Um campo de texto de várias linhas. Os utilizadores podem escrever parágrafos. O valor inclui as quebras de linha.

file

<input type="file" name="resume">

Um botão que abre o seletor de ficheiros do dispositivo. O ficheiro selecionado é enviado para o servidor. Exige enctype="multipart/form-data" no elemento do formulário.

hidden

<input type="hidden" name="user_id" value="12345">

Um campo que não é mostrado mas é enviado ao submeter. Útil para dados de acompanhamento que devem ser incluídos mas que o utilizador não deve alterar.

Etiquetas e acessibilidade

Junta sempre os campos a etiquetas.

<label for="email">Email address</label>

<input type="email" id="email" name="email">

O atributo for da etiqueta tem de corresponder ao id do campo. Quando fazes isto corretamente:

Os leitores de ecrã anunciam a etiqueta e o campo em conjunto, clicar na etiqueta dá foco ao campo, e os utilizadores de telemóvel ganham uma área de toque maior.

Nunca dispenses as etiquetas. Se precisares de esconder uma etiqueta visualmente, usa CSS para a esconder mas mantém-na no HTML. A isto chama-se uma etiqueta "visualmente oculta".

Agrupar campos relacionados

Para campos relacionados, usa fieldset e legend.

<fieldset>

<legend>Shipping address</legend>

<input type="text" name="street">

<input type="text" name="city">

</fieldset>

O elemento legend anuncia o grupo aos leitores de ecrã. Os fieldsets ajudam a organizar botões de opção e caixas de seleção, visual e semanticamente.

Submissão do formulário e métodos HTTP

Quando o utilizador clica no botão de submeter, o navegador recolhe todos os campos com nome, codifica os dados (application/x-www-form-urlencoded por defeito), envia um pedido HTTP para o URL do action com o método (POST ou GET) e espera por uma resposta.

O servidor recebe o pedido e pode processar os dados. Os dados chegam como pares chave-valor. Se o método do formulário for POST e o action for "/submit", o pedido aparece assim. POST /submit HTTP/1.1 com o Content-Type definido como application/x-www-form-urlencoded, e depois os dados aparecem como email=user@example.com&name=John.

O servidor analisa estes dados e responde. Se a resposta for uma página, o navegador carrega-a. Se a resposta for um redirecionamento, o navegador navega para o novo URL.

Validação do lado do cliente

O HTML tem atributos de validação integrados. O navegador verifica-os antes de enviar o formulário.

required

<input type="text" name="email" required>

O campo tem de ter um valor. Se ficar em branco, o formulário não é submetido e o navegador mostra um erro.

minlength e maxlength

<input type="password" name="password" minlength="8" maxlength="128">

O valor tem de ficar entre os números de caracteres indicados.

min e max

<input type="number" name="age" min="18" max="120">

Nos campos numéricos, o valor tem de estar dentro do intervalo.

pattern

<input type="text" name="zip_code" pattern="[0-9]{5}">

Uma expressão regular com a qual o valor tem de corresponder. Um código postal de cinco dígitos corresponde a [0-9]{5}.

A validação do lado do cliente é uma comodidade para os utilizadores. Evita que submetam dados inválidos e vejam um erro do servidor. Mas nunca dependas da validação do lado do cliente para a segurança. Valida sempre também no servidor.

Perceber a diferença entre type="submit" e type="button"

<button type="submit">Send</button>

<button type="button">Save</button>

Um botão com type="submit" submete o formulário quando clicado. Um botão com type="button" não faz nada por defeito. Usa type="button" quando quiseres associar manipuladores de eventos JavaScript.

Muitos programadores usam <button> sem especificar o type. Por defeito fica type="submit", que normalmente é o que queres. Mas sê explícito para evitar surpresas.

Porque deves perceber os formulários HTML

Se usas uma framework moderna de JavaScript, estás a construir em cima de formulários HTML. As frameworks abstraem os detalhes, mas os princípios de fundo são os mesmos. Um formulário continua a submeter para um endpoint. A validação continua a ter de acontecer. O servidor continua a ter de tratar os dados.

Quando algo falha no tratamento do teu formulário, perceber HTML ajuda a depurar. Sabes de onde vêm os dados, como são codificados e o que o servidor deve receber. Esta é a base.

A maioria das aplicações web modernas já não usa a submissão tradicional de formulários. Usa JavaScript para intercetar o formulário, validá-lo e enviar os dados através de _blocked_ ou de uma biblioteca de pedidos HTTP. Mas conhecer primeiro a forma HTML faz com que esses padrões façam sentido.

Como o criador de formulários da WEMASY usa estes princípios

Por baixo, o criador de formulários da WEMASY gera formulários HTML acessíveis com estes mesmos elementos. As etiquetas estão associadas aos campos. A validação é tratada tanto no cliente como no servidor. Os dados do formulário são submetidos em segurança. Se exportares ou personalizares um formulário da WEMASY, estás a trabalhar com formulários HTML construídos sobre estes fundamentos.

Vê a página de preços da WEMASY para detalhes sobre as funcionalidades de formulários e as opções de personalização.

Perguntas frequentes

Devo usar GET ou POST para submeter o meu formulário?
Usa POST em qualquer formulário que altere dados, envie informação sensível ou tenha carregamento de ficheiros. Usa GET apenas em formulários de pesquisa em que a consulta pode ficar visível no URL. O GET é menos seguro e tem limites de tamanho do URL. O POST é a escolha segura para a maioria dos formulários. Com o criador de websites da WEMASY, podes configurar isto diretamente no teu website.
A validação do lado do cliente chega ou também preciso de validação no servidor?
Valida sempre no servidor. A validação do lado do cliente serve a experiência do utilizador. Alguém pode desativar o JavaScript ou contornar as verificações do navegador. É na validação do servidor que está a segurança a sério. Faz as duas.
Como envio um formulário com JavaScript em vez da submissão por defeito?
Escuta o evento submit com addEventListener, chama event.preventDefault() e depois usa _blocked_ ou uma biblioteca de pedidos HTTP para enviar os dados. Isto permite validar, transformar ou acrescentar dados extra antes de enviar.
Qual é a diferença entre dados de formulário e JSON?
Por defeito, os formulários enviam dados como application/x-www-form-urlencoded (pares chave-valor). O JSON é um formato diferente. Quando intercetas um formulário com JavaScript e usas _blocked_ para enviar JSON, mudas o tipo de conteúdo. O servidor precisa de saber que formato esperar.
Porque devo usar elementos label em vez de pôr só texto ao lado dos campos?
As etiquetas melhoram a acessibilidade para leitores de ecrã e a navegação por teclado. Também criam uma área de clique maior no telemóvel. Se tiveres de esconder uma etiqueta visualmente, usa CSS para a esconder mas mantém-na no HTML para que as tecnologias de apoio a encontrem na mesma.
Preciso de me preocupar com a proteção CSRF nos formulários?
Sim. Se o teu formulário altera dados (cria, atualiza ou elimina), usa um token CSRF para evitar a falsificação de pedidos entre sites. Inclui um campo oculto com um token único gerado pelo servidor. Verifica o token quando o formulário for submetido.

Põe isto em prática
no teu próprio site.

Começa grátis com a WEMASY e cria o teu site em poucos minutos.