É possível fazer uma quantidade impressionante de validações de formulários e melhorar a UX apenas com atributos HTML e CSS, incrementando bastante a experiência das pessoas que os usam. Neste artigo, veja como aprimorar a UX em validação de formulários com HTML e CSS.
Label parecido com placeholder
Primeiramente: sempre use elementos <label>
reais, que são sugestões de entradas válidas ao campo, como colocar “Ex: São Paulo” em um campo “Cidade”, por exemplo.
Nos casos em que o formulário é curto (como um cadastro ou login), seria possível usar o padrão visual de placeholder, mas também é possível usar <label>
s reais, como em:
1 2 3 4 5 6 7 8 |
<form action="#0" method="post"> <div> <input type="text" id="first_name" name="first_name"> <label for="first_name">First Name</label> </div> <!-- ... ---> </form> |
Usa-se o <div>
como um contexto de posicionamento com o rótulo diretamente sobre o formulário:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
form { max-width: 450px; // contexto de posicionamento > div { position: relative; // aparência de placeholder > label { left: 20px; opacity: 0.3; position: absolute; top: 22px; } } } |
Não é necessário fazer qualquer truque de cursor, porque tudo já fica semanticamente adequado. Se acontece clique na área do rótulo, ele vai ativar a entrada; se é no campo, também. Ambos estão corretos.
O truque é colocar o campo primeiro (sem prejuízos à semântica) para esconder o label no foco, dessa maneira:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
form { // ... > div { > input[type="text"], > input[type="email"], > input[type="password"] { &:focus { & + label { opacity: 0; } } } } } |
Campos obrigatórios
Talvez a validação mais fácil possível em um formulário seja usar o atributo required
para exigir que um campo seja de preenchimento obrigatório. Não há maneira mais rápida de identificar um erro e deixar o navegador fazer o tratamento.
1 |
<input type="text" name="first_name" class="first_name" required> |
Indicar positivamente campos válidos
Permita que as pessoas saibam que houve entrada em um campo e esta é válida. Usando CSS, o navegador pode fornecer este tipo de informação através do seletor :valid
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
form { > input[type="text"], > input[type="email"], > input[type="password"] { // Mostra sucesso &:valid { background: url(images/check.svg); background-size: 20px; background-repeat: no-repeat; background-position: 20px 20px; // Esconde o label & + label { opacity: 0; } } } } |
:valid
, nesse caso, é necessário para assegurar que a condição foi satisfeita, mas o seletor também é útil para a validação do tipo de entrada.
Mostrar lembretes sobre o tipo de validação
Também é possível especificar que cada valor de uma entrada seja de um certo tipo, como e-mail ou número (eis exemplos de todos eles).
1 |
<input type="email" name="email" class="email" required> |
Essa entrada é necessária para indicar que se trata de um formato de endereço de e-mail válido. É possível fazer isso para melhorar a UX:
- Informar às pessoas sobre os requisitos quando o campo está em foco
- Lembrá-las que o campo não pode ter qualquer outro valor válido
Mas, também, não mostrar qualquer lembrete quando o campo está vazio. Também, não assumir um estado inválido. É apenas uma espécie de negativo irritante-desnecessário. A fim de fazer isso, é preciso saber se o campo está vazia ou não.
Testando se um campo tem algum valor ou não
É preciso algum trabalho em cima de :valid
e :valid
, mas não é desejável se antecipar com :valid
e usá-lo antes de o campo ter algum valor.
Existe algum seletor CSS para testar se um campo está vazia? Na verdade, não. Muita gente pensa que :empty
serve para isso, mas não serve! Ele é para estilizar coisas como <p></p>
, ou seja, elementos de contêiner sem nada dentro. Campos de formulário são elementos sem conteúdo por padrão.
O macete é se certificar que a entrada tem um valor de placeholder:
1 2 |
input:not(:placeholder-shown) { } |
Na demo, não se está usando placeholder, mas o valor de um único espaço funciona:
1 |
<input placeholder=" "> |
:placeholder-shown
é muito útil neste caso. É, basicamente, um seletor para testar se um campo atualmente tem algum valor ou não.
Infelizmente, no momento não há suporte para Firefox e IE. Com novos recursos como este, @supports
é normalmente um salvador, mas…
1 2 3 4 5 |
// Isso não funciona! @supports (input:placeholder-shown) { input:not(:placeholder-shown) { } } |
Não é possível usar @supports
para seletores, apenas para propriedades e valores (ex: @supports (display: flex)
). Testar placeholders com JavaScript e bastante simples:
1 2 3 4 5 |
let i = document.createElement( 'input' ); if ( 'placeholder' in i ) { // ... } |
Mas não parece ser uma maneira simples para testar :placeholder-shown
. Então, a solução para o caso é esperar esperar por um melhor suporte dos navegadores antes de ser usado, efetivamente, em projetos em produção. Depois que isso acontecer, é mais ou menos assim que a coisa será ser feita:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
form { > div { > input[type="text"], > input[type="email"], > input[type="password"] { // Quando campo é... // 1. NÃO vazio // 2. NÃO em foco // 3. NÃO válido &:invalid:not(:focus):not(:placeholder-shown) { // Mostra um lembrete background: pink; & + label { opacity: 0; } } // Quando um campo inválido recebe foco (e também ainda não está vazio) &:invalid:focus:not(:placeholder-shown) { // Ver as instruções de "Validações Robustas" abaixo & ~ .requirements { max-height: 200px; padding: 0 30px 20px 50px; } } } // <input> ~ // <label> ~ // <div class="requirements"> .requirements { color: red; font-style: italic; max-height: 0; overflow: hidden; padding: 0 30px 0 50px; transition: 0.28s; } } |
Validações Robustas
Validações diretamente no navegador podem ser feitas não somente com required
, type="email"
e similares; é possível, também, validar coisas como comprimento (por exemplo, comprimento mínimo de senha ou número máximo de caracteres em textareas) e até mesmo usar expressões regulares.
Por exemplo, caso se queira um campo de senha com os seguintes requisitos:
- Mínimo de 6 caracteres
- Pelo menos 1 caractere minúsculo
- Pelo menos 1 caractere maiúsculo
- Pelo menos 1 número
É possível fazer algo como:
1 |
<input type="password" name="password" placeholder=" " pattern="(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{6,}" class="password" required> |
Conclusão das técnicas de UX em validação de formulários com HTML e CSS
Para fixar os conteúdos do artigo, fica uma demo das técnicas e sugestões de UX em validação de formulários com HTML e CSS que foram abordadas — nele, consta :placeholder-shown
, o que significa que, na data de publicação deste artigo, não vai funcionar muito bem em Firefox e IE.
See the Pen Form with a bunch of HTML5 Validation and CSS3 Help by Chris Coyier (@chriscoyier) on CodePen.
Juntamente com o que é apresentado no artigo “Melhorando a interação em formulários de busca“, estas técnicas de UX para validação de formulários levarão os forms de seus ao próximos nível.