Como verificar se uma entrada está vazia com CSS

Zell Liew Blocked Unblock Seguir Seguindo 28 de dezembro

É possível saber se uma entrada está vazia apenas com CSS?

Eu tive essa pergunta quando tentei criar um componente de autocompletar para o JavaScript. Basicamente, eu queria:

  1. Ocultar um menu suspenso se a entrada estiver vazia
  2. Mostrar a lista suspensa se a entrada estiver preenchida

Eu encontrei uma maneira de fazer isso. Não é perfeito. Existem algumas nuances envolvidas, mas quero compartilhar com você.

A forma

Primeiro, vamos criar um formulário para estarmos na mesma página. Nós vamos usar um formulário simples com uma entrada.

 <form> 
<label for = "input"> Entrada </ label>
<input type = "text" id = "input" />
</ form>

Quando a entrada é preenchida, queremos mudar sua border-color para verde. Veja um exemplo do que estamos criando:

Verificando se a entrada está vazia

Eu confiei na validação do formulário HTML para verificar se a entrada estava vazia. Isso significava que eu precisava de um atributo required .

 <form> 
<label> Entrada </ label>
<tipo de entrada = "texto" nome = "entrada" id = "entrada" necessário />
</ form>

Neste ponto, funcionou bem quando a entrada foi preenchida. Fronteiras ficaram verdes.

Mas houve um problema: se o usuário inserir um espaço em branco no campo, as bordas também ficarão verdes.

Tecnicamente, isso está correto. A entrada é preenchida porque o usuário digitou algo nela.

Mas eu não queria espaços em branco para acionar um menu suspenso em branco (para o componente autocomplete).

Não foi o suficiente. Eu precisava de um cheque mais rigoroso.

Verificações adicionais

O HTML oferece a capacidade de validar entradas com expressões regulares com o atributo pattern . Eu decidi testá-lo.

Como não queria que os espaços em branco fossem reconhecidos, comecei com o padrão S+ . Este padrão significava: Um ou mais caracteres que não são um espaço em branco.

 <form> 
<label> Entrada </ label>
<input type = "text" nome = "input" id = "input" padrão requerido = " S +" />
</ form>

Com certeza, funcionou. Se um usuário inserir um espaço em branco no campo, a entrada não será validada.

Mas quando um espaço em branco é inserido (em qualquer lugar) na entrada, a entrada é invalidada.

Infelizmente, esse padrão não funcionou no meu caso de uso.

No componente Aprender Autocompletar do JavaScript, eu ensinei aos alunos como preencher uma lista de países. Os nomes de alguns países tinham espaços …

Eu tive que incluir espaços em branco na mistura.

A próxima melhor alternativa que eu poderia pensar é S+.* . Isso significa 1 ou mais caracteres que não são espaços em branco, seguidos por zero ou mais (qualquer) caracteres.

 <form> 
<label> Entrada </ label>
<input type = "text" nome = "input" id = "input" padrão requerido = " S +. *" />
</ form>

Isso funcionou! Eu posso entrar em espaços brancos na mistura agora!

Mas há mais um problema … a entrada não valida se você COMEAR com um espaço em branco …

E esse é o problema que não consegui resolver. Mais sobre isso depois.

Quando trabalhei neste artigo, me deparei com outra questão interessante: é possível estilizar um estado inválido quando a entrada é preenchida incorretamente?

Invalidando a entrada

Não queremos usar :invalid porque vamos kickstart a entrada com um estado inválido. (Quando a entrada está vazia, já é inválida).

Este é o lugar onde Chris Coyier mergulhou para o resgate com " Form Validation UX em HTML e CSS ".

No artigo, Chris fala sobre uma pseudo-classe :placeholder-shown . Pode ser usado para verificar se um espaço reservado é exibido.

A ideia é:

  1. Você adiciona um espaço reservado à sua entrada
  2. Se a entrada estiver oculta, significa que o usuário digitou algo no campo
  3. Continuar com validação (ou invalidação)

Aqui está o CSS (versão simplificada. Para a versão completa, confira o artigo de Chris ).

 / * Mostrar bordas vermelhas quando preenchidas, mas inválidas * / 
input: not (: espaço reservado mostrado) {
border-color: hsl (0, 76%, 50%);
}

Como eu tinha os estilos de validação E invalidação, tinha que garantir que os estilos válidos viessem após os estilos inválidos.

 / * Mostrar bordas vermelhas quando preenchidas, mas inválidas * / 
input: not (: espaço reservado mostrado) {
border-color: hsl (0, 76%, 50%);
}
 / * Mostrar bordas verdes quando válido * / 
entrada: válido {
border-color: hsl (120, 76%, 50%);
}

Aqui está uma demonstração para você brincar:

Veja a validação do Pen Pure CSS Empty por Zell Liew ( @zellwk ) no CodePen .

Nota: o Edge não suporta :placeholder-shown , por isso provavelmente não é uma boa ideia usá-lo ainda na produção. Não há uma boa maneira de detectar esse recurso.

Agora, de volta ao problema, não consegui resolver.

O problema com o padrão

O atributo pattern é maravilhoso porque permite aceitar uma expressão regular. Essa expressão regular permite validar a entrada com qualquer coisa que você possa imaginar.

Mas… a expressão regular deve corresponder completamente ao texto . Se o texto não for correspondido completamente, a entrada será invalidada.

Isso criou o problema que mencionei acima. (Lembrete do problema: Se um usuário inserir um espaço em branco primeiro, a entrada se tornará inválida).

Não consegui encontrar uma expressão regular que funcionasse para todos os casos de uso em que eu pensava. Se você quiser tentar criar uma expressão regular que eu precise, ficarei mais do que feliz em receber a ajuda!

Aqui estão os casos de uso:

 // não deve corresponder 
''
''
''
''
 // deve corresponder 
'uma palavra'
'uma palavra '
' uma palavra'
' uma palavra '
'uma frase com espaço em branco'
'uma frase com espaço em branco'
'uma frase com espaço em branco'
'uma frase com espaço em branco'

(Então, novamente, eu posso estar pensando demais … ?).

Atualização: problema resolvido!

Muitos leitores foram generosos o suficiente para me enviar suas soluções. Quero agradecer a todos que ajudaram. Muito obrigado!

A solução mais limpa que recebi é: .*S.* por Daniel O'Connor . Isso significa:

  • .* : Qualquer personagem
  • S : seguiu um caractere sem espaço em branco
  • .* : Seguido por qualquer personagem

Outras expressões regulares que recebi incluem:

E muitos outros!

Aqui está um codepen com a solução atualizada de Daniel.

Empacotando

Sim, é possível validar um formulário com CSS puro. Existem problemas potenciais com a validação quando os caracteres de espaço em branco estão envolvidos.

Se você não se importa com os espaços em branco, funciona perfeitamente. Divirta-se tentando este padrão fora! (Desculpe, não posso evitar).

Obrigado pela leitura. Este artigo ajudou você? Se sim, espero que você considere compartilhá-lo . Você pode ajudar outra pessoa. Muito obrigado!