Bootstrap: Formulários e Validação de Formulário
Última atualização: 2026-08-26
1. Introdução
(1) Pré-requisitos
- Lição 12: Tabelas
(2) 🎯 O que você vai aprender
- Estilizar controles usando
form-control,form-select,form-check-input - Dispor formulários usando grade e layouts em linha
- Adicionar elementos de prefixo/sufixo usando
input-group - Implementar validação no cliente usando
needs-validation - Implementar rótulos flutuantes usando
form-floating
(3) O Ponto de Dor
O Bob está desenvolvendo uma página de registro de usuário e precisa coletar nome, e-mail, senha, seleção de país e concordância com os termos—as classes de formulário do Bootstrap permitem que ele pule escrever qualquer CSS, focando apenas na estrutura HTML e na lógica de validação.
(4) A Solução
Formulários são o modo central de interagir com usuários. O Bootstrap fornece um conjunto unificado de estilos de controle de formulário e um sistema de feedback de validação, tornando o desenvolvimento de formulários eficiente e esteticamente agradável.
Como Entender: Formulários do Bootstrap = um filtro de beleza para os controles nativos do navegador—todos os elementos
<input>,<select>,<textarea>ganham estilos unificados, espaçamento e feedback interativo quando envolvidos com.form-control.
(5) O Benefício
Usando as classes utilitárias de formulário do Bootstrap, você pode focar na estrutura HTML e na lógica de validação sem escrever nenhum código de estilo CSS.
2. Controles de Formulário
Todos os controles de input baseados em texto usam .form-control:
▶ Exemplo: Formulário Básico
<!DOCTYPE html>
<html lang="pt-br">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Demonstração de Formulário</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container py-4">
<form>
<div class="mb-3">
<label for="name" class="form-label">Nome Completo</label>
<input type="text" class="form-control" id="name" placeholder="Digite seu nome">
</div>
<div class="mb-3">
<label for="country" class="form-label">País</label>
<select class="form-select" id="country">
<option selected>Escolher...</option>
<option value="us">Estados Unidos</option>
<option value="jp">Japão</option>
<option value="uk">Reino Unido</option>
</select>
</div>
<div class="mb-3">
<label class="form-label">Habilidades</label>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="html" checked>
<label class="form-check-label" for="html">HTML</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="css">
<label class="form-check-label" for="css">CSS</label>
</div>
</div>
<div class="mb-3">
<label class="form-label">Nível de Experiência</label>
<div class="form-check">
<input class="form-check-input" type="radio" name="level" id="beginner" checked>
<label class="form-check-label" for="beginner">Iniciante</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="level" id="advanced">
<label class="form-check-label" for="advanced">Avançado</label>
</div>
</div>
<button type="submit" class="btn btn-primary">Enviar</button>
</form>
</div>
</body>
</html>
Output: Bootstrap 5.3 styled component effects (like buttons, cards, carousels, collapses, etc.). The page uses Bootstrap's default theme (light) and responsive grid by default.
3. Tipos de Controle de Formulário
| Controle | Classe | Descrição |
|---|---|---|
| Input de texto | form-control |
Texto de linha única, e-mail, senha, url, etc. |
| Textarea | form-control |
Texto multi-linha (rows controla o número de linhas) |
| Select | form-select |
Caixa de seleção dropdown |
| Caixa de seleção | form-check-input |
Múltipla seleção |
| Rádio | form-check-input |
Seleção única (exclusivo com o mesmo nome) |
| Intervalo | form-range |
Slider |
| Arquivo | form-control |
Upload de arquivo |
4. Layout de Formulário
(1) Layout em Grade
<div class="row">
<div class="col-md-6 mb-3">
<label for="firstName" class="form-label">Nome</label>
<input type="text" class="form-control" id="firstName">
</div>
<div class="col-md-6 mb-3">
<label for="lastName" class="form-label">Sobrenome</label>
<input type="text" class="form-control" id="lastName">
</div>
</div>
Output: Bootstrap 5.3 styled component effects (like buttons, cards, carousels, collapses, etc.). The page uses Bootstrap's default theme (light) and responsive grid by default.
(2) Formulário em Linha
<form class="row g-3">
<div class="col-auto">
<input type="search" class="form-control" placeholder="Buscar...">
</div>
<div class="col-auto">
<button class="btn btn-primary" type="submit">Ir</button>
</div>
</form>
Output: Bootstrap 5.3 styled component effects (like buttons, cards, carousels, collapses, etc.). The page uses Bootstrap's default theme (light) and responsive grid by default.
(3) Formulário Horizontal
<div class="row mb-3">
<label for="email2" class="col-sm-2 col-form-label">E-mail</label>
<div class="col-sm-10">
<input type="email" class="form-control" id="email2">
</div>
</div>
Output: Bootstrap 5.3 styled component effects (like buttons, cards, carousels, collapses, etc.). The page uses Bootstrap's default theme (light) and responsive grid by default.
5. Grupos de Input
<div class="input-group mb-3">
<span class="input-group-text">@</span>
<input type="text" class="form-control" placeholder="Nome de usuário">
</div>
<div class="input-group mb-3">
<input type="text" class="form-control" placeholder="Valor">
<span class="input-group-text">,00</span>
</div>
<div class="input-group mb-3">
<button class="btn btn-outline-secondary" type="button">Buscar</button>
<input type="text" class="form-control" placeholder="Digite para buscar">
</div>
Output: Bootstrap 5.3 styled component effects (like buttons, cards, carousels, collapses, etc.). The page uses Bootstrap's default theme (light) and responsive grid by default.
6. Validação de Formulário
<form class="row g-3 needs-validation" novalidate>
<div class="col-md-4">
<label for="validationName" class="form-label">Nome</label>
<input type="text" class="form-control" id="validationName" required>
<div class="valid-feedback">Parece bom!</div>
<div class="invalid-feedback">Por favor, digite seu nome.</div>
</div>
<div class="col-md-4">
<label for="validationEmail" class="form-label">E-mail</label>
<input type="email" class="form-control" id="validationEmail" required>
<div class="valid-feedback">E-mail válido!</div>
<div class="invalid-feedback">Por favor, forneça um e-mail válido.</div>
</div>
<div class="col-12">
<button class="btn btn-primary" type="submit">Enviar</button>
</div>
</form>
<script>
(function() {
var forms = document.querySelectorAll('.needs-validation')
Array.prototype.slice.call(forms).forEach(function(form) {
form.addEventListener('submit', function(event) {
if (!form.checkValidity()) {
event.preventDefault()
event.stopPropagation()
}
form.classList.add('was-validated')
}, false)
})
})()
</script>
Output: Bootstrap 5.3 styled component effects (like buttons, cards, carousels, collapses, etc.). The page uses Bootstrap's default theme (light) and responsive grid by default.
(1) Estilos de Feedback de Validação
| Classe | Condição | Método de Exibição |
|---|---|---|
.valid-feedback |
Input é válido | Texto verde |
.invalid-feedback |
Input é inválido | Texto vermelho |
.was-validated |
Após envio do formulário | Dispara todo o feedback |
is-valid / is-invalid |
Controle manual | Borda de status |
7. Mais Exemplos de Formulário
▶ Exemplo: Formulário de Registro Completo (com Validação)
<!DOCTYPE html>
<html lang="pt-br">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Formulário de Cadastro</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container py-4">
<div class="card mx-auto" style="max-width: 500px;">
<div class="card-header bg-primary text-white">
<h4 class="mb-0">Criar Conta</h4>
</div>
<div class="card-body">
<form class="needs-validation" novalidate>
<div class="mb-3">
<label for="fullName" class="form-label">Nome Completo</label>
<input type="text" class="form-control" id="fullName" required>
<div class="invalid-feedback">Por favor, digite seu nome.</div>
</div>
<div class="mb-3">
<label for="signupEmail" class="form-label">E-mail</label>
<input type="email" class="form-control" id="signupEmail" required>
<div class="invalid-feedback">Por favor, forneça um e-mail válido.</div>
</div>
<div class="row mb-3">
<div class="col-md-6">
<label for="password" class="form-label">Senha</label>
<input type="password" class="form-control" id="password" minlength="8" required>
<div class="invalid-feedback">A senha deve ter pelo menos 8 caracteres.</div>
</div>
<div class="col-md-6">
<label for="confirmPwd" class="form-label">Confirmar</label>
<input type="password" class="form-control" id="confirmPwd" required>
<div class="invalid-feedback">As senhas devem coincidir.</div>
</div>
</div>
<div class="mb-3">
<label for="countrySelect" class="form-label">País</label>
<select class="form-select" id="countrySelect" required>
<option value="">Escolher...</option>
<option value="us">Estados Unidos</option>
<option value="uk">Reino Unido</option>
<option value="jp">Japão</option>
</select>
<div class="invalid-feedback">Por favor, selecione um país.</div>
</div>
<div class="mb-3 form-check">
<input type="checkbox" class="form-check-input" id="agreeTerms" required>
<label class="form-check-label" for="agreeTerms">Eu concordo com os termos e condições</label>
<div class="invalid-feedback">Você deve concordar para continuar.</div>
</div>
<button type="submit" class="btn btn-primary w-100">Registrar</button>
</form>
</div>
</div>
</div>
<script>
(function() {
var forms = document.querySelectorAll('.needs-validation')
Array.prototype.slice.call(forms).forEach(function(form) {
form.addEventListener('submit', function(event) {
if (!form.checkValidity()) {
event.preventDefault()
event.stopPropagation()
}
form.classList.add('was-validated')
}, false)
})
})()
</script>
</body>
</html>
Output: Bootstrap 5.3 styled component effects (like buttons, cards, carousels, collapses, etc.). The page uses Bootstrap's default theme (light) and responsive grid by default.
▶ Exemplo: Formulário de Busca (Grupo de Input)
<form class="container py-4">
<div class="row g-2">
<div class="col-md-3">
<select class="form-select">
<option selected>Todas as Categorias</option>
<option value="electronics">Eletrônicos</option>
<option value="clothing">Roupas</option>
<option value="books">Livros</option>
</select>
</div>
<div class="col-md-6">
<div class="input-group">
<input type="search" class="form-control" placeholder="Buscar produtos...">
<button class="btn btn-primary" type="submit">Buscar</button>
</div>
</div>
<div class="col-md-3">
<button class="btn btn-outline-secondary w-100" type="button">Filtros Avançados</button>
</div>
</div>
</form>
Output: Bootstrap 5.3 styled component effects (like buttons, cards, carousels, collapses, etc.). The page uses Bootstrap's default theme (light) and responsive grid by default.
▶ Exemplo: Formulário em Linha
<form class="row row-cols-lg-auto g-3 align-items-center">
<div class="col-12">
<input type="text" class="form-control" placeholder="Usuário">
</div>
<div class="col-12">
<input type="password" class="form-control" placeholder="Senha">
</div>
<div class="col-12">
<div class="form-check">
<input class="form-check-input" type="checkbox" id="rememberMe">
<label class="form-check-label" for="rememberMe">Lembrar de mim</label>
</div>
</div>
<div class="col-12">
<button type="submit" class="btn btn-primary">Entrar</button>
</div>
</form>
Output: Bootstrap 5.3 styled component effects (like buttons, cards, carousels, collapses, etc.). The page uses Bootstrap's default theme (light) and responsive grid by default.
▶ Exemplo: Formulário com Rótulo Flutuante
<div class="container py-4" style="max-width: 400px;">
<form>
<div class="form-floating mb-3">
<input type="email" class="form-control" id="floatingEmail" placeholder="nome@exemplo.com">
<label for="floatingEmail">Endereço de e-mail</label>
</div>
<div class="form-floating mb-3">
<input type="password" class="form-control" id="floatingPassword" placeholder="Senha">
<label for="floatingPassword">Senha</label>
</div>
<div class="form-floating mb-3">
<select class="form-select" id="floatingSelect">
<option value="">Escolher...</option>
<option value="free">Plano Grátis</option>
<option value="pro">Plano Pro</option>
<option value="enterprise">Empresarial</option>
</select>
<label for="floatingSelect">Plano de Assinatura</label>
</div>
<div class="form-floating mb-3">
<textarea class="form-control" id="floatingTextarea" style="height: 100px" placeholder="Comentários"></textarea>
<label for="floatingTextarea">Mensagem</label>
</div>
<button class="btn btn-primary w-100">Enviar</button>
</form>
</div>
Output: Bootstrap 5.3 styled component effects (like buttons, cards, carousels, collapses, etc.). The page uses Bootstrap's default theme (light) and responsive grid by default.
(1) Fluxo de Decisão de Layout de Formulário
flowchart TD
A[Iniciar design do formulário] --> B{Número de campos}
B -->|1-3| C[Empilhamento simples<br/>separar com mb-3]
B -->|4-8| D{Precisa agrupar?}
D -->|Sim| E[Layout em grade<br/>row + col-*]
D -->|Não| F[Layout em linha/horizontal]
B -->|8+| G[Grade multi-coluna<br/>ou passo a passo]
E --> H{Precisa prefixo?}
H -->|Sim| I[input-group]
H -->|Não| J[form-control direto]
F --> K{Rótulo flutuante?}
K -->|Sim| L[form-floating]
K -->|Não| M[Rótulo regular]
Output: Bootstrap 5.3 styled component effects (like buttons, cards, carousels, collapses, etc.). The page uses Bootstrap's default theme (light) and responsive grid by default.
| Controle de Formulário | Classe | Tipos de Dados Aplicáveis |
|---|---|---|
| Texto de linha única | form-control |
Nome, e-mail, senha |
| Texto multi-linha | form-control (textarea) |
Comentários, descrições |
| Seleção dropdown | form-select |
País, categoria, opções |
| Caixa de seleção | form-check-input |
Múltipla seleção, concordância com termos |
| Botão de rádio | form-check-input (radio) |
Gênero, nível, opções |
| Slider | form-range |
Faixa de preço, avaliação |
| Upload de arquivo | form-control (file) |
Imagens, documentos |
| Variante de Grupo de Input | Padrão de Código | Caso de Uso |
|---|---|---|
| Texto de prefixo | input-group-text + form-control |
Valor $, prefixo @ de usuário |
| Texto de sufixo | form-control + input-group-text |
Sufixo ,00, unidade px |
| Botão de prefixo | button + form-control |
Caixa de busca |
| Botão de sufixo | form-control + button |
Alternar visibilidade de senha |
| Múltiplos elementos | Múltiplos input-group-text |
Faixa de datas, input combinado |
| Estado de Validação | Classe | Borda | Texto de Feedback |
|---|---|---|---|
| Válido | is-valid |
Verde | valid-feedback |
| Inválido | is-invalid |
Vermelho | invalid-feedback |
| Após envio | was-validated |
Alterna automaticamente | Dispara todo o feedback |
| Tooltip | Combinado com valid-tooltip |
Igual acima | Dica estilo balão |
❓ Perguntas Frequentes
P: Por que os controles de formulário não têm sua própria largura? R:
.form-controltemwidth: 100%por padrão. Para controlar a largura, coloque-o dentro de uma coluna de grade (col-*) ou adicionestyle="width: 300px".
P: Qual a finalidade de
.form-label? R: Ela unifica o espaçamento (margin-bottom: 0.5rem) e o tamanho de fonte do<label>. Funciona sem ele, mas adicioná-lo é recomendado para consistência.
P: Posso personalizar as mensagens de erro na validação de formulário? R: Sim. O texto dentro de
<div class="invalid-feedback">pode ser qualquer coisa que você quiser. Além disso, o métodosetCustomValidity()é suportado.
P: Grupos de input podem aninhar múltiplos elementos? R: Sim. Um
input-grouppode conter múltiplosinput-group-text,form-controle botões.
P: Rótulos flutuantes (form-floating) suportam todos os navegadores? R: Rótulos flutuantes usam a pseudo-classe CSS
:placeholder-shown, suportada por navegadores modernos. O IE não suporta, mas o IE cessou manutenção. Se precisar suportar navegadores muito antigos, recomenda-se usar layouts de rótulo tradicionais.
📖 Resumo
- Use
form-controlpara controles de texto,form-selectpara dropdowns,form-check-inputpara caixas de seleção/rádio - Use
mb-3para separar grupos de formulário, e graderow+col-*para layouts multi-coluna - Use
input-grouppara adicionar texto/botões antes ou depois de um campo de input - Validação de formulário:
needs-validation+ JS +was-validated+valid-feedback/invalid-feedback
📝 Exercícios
- ⭐ Crie um formulário de registro completo: nome (texto), idade (número), país (select), senha (senha), confirmar senha, todos usando estilos do Bootstrap.
- ⭐⭐ Implemente validação para o formulário do Exercício 1: nome é obrigatório, 2-20 caracteres; senha deve ter pelo menos 8 caracteres; e-mail deve estar no formato correto. Exiba um
invalid-feedbackvermelho quando as condições não forem atendidas. - ⭐⭐⭐ Crie um grupo de input de busca: um
form-selectà esquerda para seleção de categoria + uma caixa de buscaform-controlno meio + um botão Buscar à direita.
Lição Anterior: Tabelas · Próxima Lição: Carrossel e Modal