Formulário que trava (sw-trava) CSS
O botão "Enviar" fica apagado até a pessoa preencher tudo certo, e o campo errado só fica vermelho depois que ela mexeu nele. Sem JavaScript.
O que é
Coloque sw-trava na tag <form> e pronto: enquanto faltar um campo obrigatório ou tiver um e-mail mal digitado, o botão de enviar fica apagado e não aceita clique. Quando tudo estiver certo, ele acende. Os campos que a pessoa já preencheu ganham borda verde (certo) ou vermelha (errado) — mas só depois que ela mexeu, para não "gritar" com ninguém antes de começar.
É só CSS. O SW Core usa as regras que o próprio HTML já tem: required (obrigatório), type="email", minlength (mínimo de letras), pattern (formato) etc. O navegador sabe se cada campo está certo, e o CSS apaga o botão de envio enquanto houver algum errado. Funciona com os campos do SW Core (sw-fld / sw-inp) ou com campos comuns.
Quando usar
- Formulário de contato ou de orçamento: evita a mensagem chegar sem e-mail ou telefone.
- Cadastro e newsletter: o botão só libera com o e-mail certo e o "aceito os termos" marcado.
- Agendamento: não deixa enviar sem data e horário.
- Precisa de mensagem de erro escrita embaixo do campo ("Digite um e-mail válido")? Some com a Validação do SW Core — as duas funcionam juntas.
Comece aqui
-
1
Coloque o SW Core no
<head>. A trava é só CSS: não precisa do arquivo de JavaScript.<link rel="stylesheet" href="swcore/swcore.min.css"> -
2
Ponha
sw-travano<form>erequirednos campos obrigatórios. Digite um e-mail aqui e veja o botão acender:<form sw-trava action="/newsletter" method="post" class="flx f-wr alc gap-3"> <input sw-inp type="email" name="email" required placeholder="seu@email.com" aria-label="E-mail"> <button sw-btn="pri">Quero receber</button> </form>
Todas as variações
Cada quadro abaixo é o componente de verdade, rodando. O código embaixo é exatamente o que está no quadro: copie e cole.
1. As regras do HTML que ele respeita
Cada quadro é um formulário com sw-trava e uma regra diferente. O botão só acende quando a regra é cumprida. Clique fora do campo depois de digitar para ver a borda vermelha ou verde. (Os quadros não enviam nada.)
<form sw-trava class="flx f-cl gap-2">
<input sw-inp required placeholder="Seu nome" aria-label="Nome">
<button sw-btn="pri p">Enviar</button>
</form>
<form sw-trava class="flx f-cl gap-2">
<input sw-inp type="email" required placeholder="seu@email.com" aria-label="E-mail">
<button sw-btn="pri p">Enviar</button>
</form>
<form sw-trava class="flx f-cl gap-2">
<input sw-inp type="password" required minlength="8" placeholder="Senha (8+ letras)" aria-label="Senha">
<button sw-btn="pri p">Criar conta</button>
</form>
<form sw-trava class="flx f-cl gap-2">
<input sw-inp required pattern="[0-9]{5}-?[0-9]{3}" inputmode="numeric" placeholder="00000-000" aria-label="CEP">
<button sw-btn="pri p">Calcular frete</button>
</form>
<form sw-trava class="flx f-cl gap-2">
<label sw-chk><input type="checkbox" required> Aceito os termos</label>
<button sw-btn="pri p">Continuar</button>
</form>
<form sw-trava class="flx f-cl gap-2">
<select sw-inp required aria-label="Horário">
<option value="">Escolha o horário</option>
<option>09:00</option>
<option>14:00</option>
</select>
<button sw-btn="pri p">Agendar</button>
</form>
2. Botões que ele trava e que ele deixa em paz
A trava apaga o botão de enviar: todo <button> sem tipo (o padrão do HTML é enviar) e todo type="submit". Botão com type="button" continua clicável — use nele "Cancelar", "Limpar", ajuda etc.
<form sw-trava class="flx f-wr alc gap-3">
<input sw-inp type="tel" required placeholder="(00) 00000-0000" aria-label="WhatsApp">
<button type="button" sw-btn="ghost sec">Cancelar</button>
<button type="submit" sw-btn="suc">Me chame no WhatsApp</button>
</form>
Tabela de opções
| Palavra | O que faz | Exemplo |
|---|---|---|
| No formulário | ||
sw-trava | Liga a trava do botão de enviar e as bordas verde/vermelha. Vai na tag <form>. | <form sw-trava> |
| Regras do HTML (nos campos) | ||
required | Campo obrigatório. Em checkbox: tem que estar marcado. Em select: a primeira opção precisa ter value="". | <input required> |
type="email" | Aceita só e-mail (tem que ter @ e domínio). | <input type="email"> |
type="url" | Aceita só endereço de site (começando com http:// ou https://). | <input type="url"> |
minlength / maxlength | Mínimo / máximo de letras. | <input minlength="8"> |
min / max | Menor / maior número ou data aceita. | <input type="number" min="1" max="10"> |
pattern | Formato exigido (expressão regular). Ex.: CEP, placa, telefone. | pattern="[0-9]{5}-?[0-9]{3}" |
| Botões | ||
<button> (sem type) | É botão de enviar: fica apagado enquanto houver erro. | <button sw-btn="pri">Enviar</button> |
type="submit" | Também fica apagado enquanto houver erro. | <button type="submit"> |
type="button" | Não é afetado: continua clicável. | <button type="button">Cancelar</button> |
Receitas prontas — usos reais
Situações que aparecem em quase todo site. Copie a que servir.
<form sw-trava action="/contato" method="post" class="flx f-cl gap-3">
<div sw-fld="float">
<input sw-inp id="nome" name="nome" required placeholder=" ">
<label for="nome">Seu nome</label>
</div>
<div sw-fld="float">
<input sw-inp id="email" name="email" type="email" required placeholder=" ">
<label for="email">E-mail</label>
</div>
<div sw-fld="float">
<textarea sw-inp id="msg" name="mensagem" required minlength="10" placeholder=" "></textarea>
<label for="msg">Como podemos ajudar?</label>
</div>
<label sw-chk><input type="checkbox" name="aceite" required> Concordo em receber o retorno por e-mail</label>
<button sw-btn="pri">Enviar mensagem</button>
</form>
<form sw-trava action="/agendar" method="post" class="flx f-cl gap-3">
<div sw-fld>
<label for="dia">Dia</label>
<input sw-inp id="dia" name="dia" type="date" required>
</div>
<div sw-fld>
<label for="hora">Horário</label>
<select sw-inp id="hora" name="hora" required>
<option value="">Escolha</option>
<option>09:00</option>
<option>10:30</option>
<option>14:00</option>
</select>
</div>
<div sw-fld>
<label for="zap">WhatsApp</label>
<input sw-inp id="zap" name="whatsapp" type="tel" required pattern="[0-9 ()-]{10,}" placeholder="(00) 00000-0000">
</div>
<button sw-btn="suc"><i class="swi-calendar-check"></i> Confirmar horário</button>
</form>
<form sw-trava action="/newsletter" method="post" class="flx f-wr alc gap-2">
<input sw-inp type="email" name="email" required placeholder="Seu melhor e-mail" aria-label="E-mail">
<button sw-btn="pri"><i class="swi-envelope"></i> Assinar</button>
</form>
Precisa de quê
swcore.min.css— a trava.swcore.compl.min.css— só se usar íconeswi-*no botão.
Cuidados — erros comuns
- Sem nenhuma regra (
required,type="email"…) nos campos, a trava não tem o que conferir: o botão fica sempre aceso. - Botão de ajuda, "mostrar senha" ou "Cancelar" dentro do form precisa de
type="button"— senão a trava apaga ele também (e, sem o type, ele ainda enviaria o formulário). - Em
<select required>, a primeira opção ("Escolha…") tem que tervalue="", senão ela conta como escolhida. - A trava é conforto para quem preenche. Sempre confira os dados de novo no servidor: qualquer pessoa pode enviar dados sem passar pelo formulário.
- O botão só fica apagado visualmente e sem clique; a tecla Enter dentro de um campo ainda pode tentar enviar — aí o próprio navegador barra e mostra o aviso dele.
O que ele não faz
- Não escreve mensagem de erro embaixo do campo — só pinta a borda. Para mensagens, use a Validação (
sw-valid). - Não confere regra que depende de outro campo (ex.: "repetir senha igual à senha") nem consulta o servidor (ex.: "e-mail já cadastrado").

