Em HTML temos a tag <form> que é usada para a criação de formulários. Formulários são estruturas do HTML responsáveis por receber dados do usuário e fazer alguma coisa com esses dados. Esses dados podem ser enviados para um servidor web ou serem usados pelo próprio website. É comum usar formulários para realizar login em páginas web, para responder questionários, etc.
Um formulário pode receber vários widgets diferentes, tais como botões, caixas de seleção, caixas de texto, inputs numéricos, textuais, etc, e muitas vezes esses elementos estão associados a uma legenda que orienta o usuário, informando o que ele deve fazer.
Formulários grandes são desencorajados por quem trabalha com UX (User Experience, ou experiência do usuário), que é uma tendência em web e mobile. Ninguém quer criar um site ou um app com um formulário gigantesco que afaste seus usuários.
Abaixo vou dar um exemplo de um formulário simples e dentro dele vou usar algumas das principais estruturas usadas em formulários HTML.
A estrutura básica de um formulário é a seguinte:
<form action="/pag-responsavel-por-processar-ou-receber-os-dados" method="POST">
</form>
Cada formulário pode ter diversos atributos, mas os mais comuns e principais são o "action" e o "method". O atributo action define a URL que é responsável por receber os dados do usuário e fazer o que for necessário, seja enviar para um banco de dados, seja processar de alguma forma, etc.
Já o atributo "method" define o método do protocolo HTTP que irá ser responsável pelo envio dos dados, que podem ser GET ou POST nesse caso. Posso detalhar mais o protocolo HTTP em outro tópico, aqui eu vou ser bem breve:
Ao acessar qualquer página web, estamos mandando um GET por meio do protocolo HTTP para aquela URL e o resultado é a renderização do HTML em nosso browser. Os parâmetros necessários para realizar um GET são passados no cabeçalho da requisição, que no nosso caso aqui é a URL. Por essa característica, caso estivéssemos nos logando em um website por meio de um formulário e o "method" do <form> fosse um GET e não um POST, nossa URL mostrada após apertar o botão de realizar login seria algo assim:
127.0.0.1:3333/login?email=thiagodias%40example.com.br&senha=minhasenhavulneravel1234567
Vejam que meu email de login e minha senha aparecem na URL, o que por si só é uma grande falha de segurança. Fica muito fácil descobrir a senha nesse caso e invadir minha conta.
Já caso o "method" do <form> seja um POST, os dados do formulário são enviados no corpo da requisição HTTP e não no cabeçalho. O resultado prático disso é que os dados recebidos não aparecem na URL, embora possam ser vistos facilmente caso inspecionemos a requisição. A forma mais segura de envio desses dados é caso seja usada a versão mais segura do HTTP que é o HTTPS, que criptografa os dados, mas já estou fugindo muito do escopo deste tópico.
Continuando a criação de nosso formulário, eu vou separar os principais campos em contêineres usando a tag <div>, que semanticamente indica que o bloco de código html inserido nela é um contêiner, tornando mais fácil a estilização ou o posicionamento de objetos na minha página web:
<form action="/pag-responsavel-por-processar-ou-receber-os-dados" method="POST">
<div>
<label for="nome">Nome:</label>
<input type="text" id="nome" />
</div>
<div>
<label for="email">E-mail:</label>
<input type="email" id="email" />
</div>
<div>
<label for="message">Mensagem:</label>
<textarea id="message" cols="30" rows="10"></textarea>
</div>
<div>
<button type="submit">Enviar</button>
</div>
</form>
Temos como resultado:
![]()

O atributo "for" em cada label vincula a label a um campo do formulário. Ao clicar na label, na nossa página web, o cursor da página já irá habilitar a caixa de input graças ao uso do atributo "for". Foi o que aconteceu acima, quando eu clico na label "Nome", o seletor já seleciona a caixa de texto. Isso acontece devido ao atributo "for".
Em seguida, a tag <input> é a que cria as caixas de texto associadas a cada label. Ela é uma tag que não recebe a tag de fechamento em seguida, ela se "auto fecha", dessa forma <input /> e não <input></input>.
O atributo "type" em <input> indica o tipo de texto que queremos do usuário. No caso do nome, é um type text, no caso do email, type email, então, o navegador vai esperar um texto parecido com um email do usuário. Caso eu digite um texto sem um @por exemplo o navegador vai reclamar e pedir um email:

Há também outros tipos de texto que podem ser inseridos como atributo de input em type, como number, date, password, etc. Para verem mais sobre isso:
https://www.w3schools.com/tags/tag_input.aspEm seguida, temos a tag <textarea> que desenha a caixa de texto acima. Posso mudar a quantidade de linhas e de colunas padrão alterando os valores nos atributos "cols" e "rows".
Por fim, a tag <button> desenha um botão e associa uma ação a ele. No nosso caso, a ação está dentro do atributo "type", e foi uma ação de "submit", que é submeter os dados do nosso formulário para a URL responsável, que está definida dentro do atributo "action" em <form>. Caso eu aperte o botão agora, nada irá acontecer pois a página responsável por fazer qualquer coisa com os dados não existe ainda.
Podemos também, em vez de usar type="submit", usar type="button", que fará com que o botão não realize nenhuma ação, e personalizamos essa ação usando JavaScript. É assunto pra depois.
Nosso formulário tá bem feinho, bem quadradão. Eu poderia estilizá-lo com CSS, mas como não abordei nada de CSS e o post já tá grande demais, fica a curiosidade pra depois.