Respostas:
Se apenas o campo é que required
você poderia ir cominput:valid
#foo-thing:valid + .msg { visibility: visible!important; }
<input type="text" id="foo-thing" required="required">
<span class="msg" style="visibility: hidden;">Yay not empty</span>
Veja ao vivo em jsFiddle
OU negar o uso #foo-thing:invalid
(crédito para @SamGoody)
Nos navegadores modernos, você pode usar :placeholder-shown
para direcionar a entrada vazia (não deve ser confundida ::placeholder
).
input:placeholder-shown {
border: 1px solid red; /* Red border only if the input is empty */
}
Mais informações e suporte ao navegador: https://css-tricks.com/almanac/selectors/p/placeholder-shown/
Não há seletor em CSS que faça isso. Os seletores de atributo correspondem aos valores dos atributos, não aos valores calculados.
Você precisaria usar JavaScript.
A atualização do valor de um campo não atualiza seu atributo value no DOM; é por isso que seu seletor sempre corresponde a um campo, mesmo quando ele não está vazio.
Em vez disso, use a invalid
pseudo-classe para alcançar o que deseja, da seguinte maneira:
input:required {
border: 1px solid green;
}
input:required:invalid {
border: 1px solid red;
}
<input required type="text" value="">
<input required type="text" value="Value">
input[value=""], input:not([value])
funciona com:
<input type="text" />
<input type="text" value="" />
Mas o estilo não será alterado assim que alguém começar a digitar (você precisa de JS para isso).
input[value=""], input:not([value])
.
Se suportam navegadores antigos não é necessário, você pode usar uma combinação de required
, valid
e invalid
.
A coisa boa sobre como usar esse é o valid
e invalid
pseudo-elementos funcionam bem com os atributos de tipo de campos de entrada. Por exemplo:
input:invalid, textarea:invalid {
box-shadow: 0 0 5px #d45252;
border-color: #b03535
}
input:valid, textarea:valid {
box-shadow: 0 0 5px #5cd053;
border-color: #28921f;
}
<input type="email" name="email" placeholder="john_doe@example.com" required />
<input type="url" name="website" placeholder="http://johndoe.com"/>
<input type="text" name="name" placeholder="John Doe" required/>
Para referência, JSFiddle aqui: http://jsfiddle.net/0sf6m46j/
$('input#edit-keys-1').blur(function(){
tmpval = $(this).val();
if(tmpval == '') {
$(this).addClass('empty');
$(this).removeClass('not-empty');
} else {
$(this).addClass('not-empty');
$(this).removeClass('empty');
}
});
em jQuery. Eu adicionei uma classe e estilizei com css.
.empty { background:none; }
Isso funcionou para mim:
Para o HTML, inclua o required
atributo no elemento de entrada
<input class="my-input-element" type="text" placeholder="" required />
Para o CSS, use o :invalid
seletor para direcionar a entrada vazia
input.my-input-element:invalid {
}
Notas:
required
a partir w3Schools.com : "Quando presente, ele especifica que um campo de entrada deve ser preenchido antes de submeter o formulário"Essa pergunta pode ter sido feita há algum tempo, mas, como eu recentemente entrei nesse tópico, procurando validação de formulário do lado do cliente e, como o :placeholder-shown
suporte está melhorando, pensei que o seguinte poderia ajudar outras pessoas.
Usando Berend idéia de de usar essa pseudo classe CSS4, consegui criar uma validação de formulário acionada somente depois que o usuário terminava de preenchê-lo.
Aqui está um exemplo e explicação sobre o CodePen: https://codepen.io/johanmouchet/pen/PKNxKQ
Se você estiver feliz por não oferecer suporte ao IE ou ao Edge anterior ao Chromium (o que pode ser bom se você estiver usando isso para aprimoramento progressivo), use :placeholder-shown
como Berend disse. Observe que, para o Chrome e o Safari, você realmente precisa de um espaço reservado não vazio para que isso funcione, embora um espaço funcione.
*,
::after,
::before {
box-sizing: border-box;
}
label.floating-label {
display: block;
position: relative;
height: 2.2em;
margin-bottom: 1em;
}
label.floating-label input {
font-size: 1em;
height: 2.2em;
padding-top: 0.7em;
line-height: 1.5;
color: #495057;
background-color: #fff;
background-clip: padding-box;
border: 1px solid #ced4da;
border-radius: 0.25rem;
transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
}
label.floating-label input:focus {
color: #495057;
background-color: #fff;
border-color: #80bdff;
outline: 0;
box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);
}
label.floating-label input+span {
position: absolute;
top: 0em;
left: 0;
display: block;
width: 100%;
font-size: 0.66em;
line-height: 1.5;
color: #495057;
border: 1px solid transparent;
border-radius: 0.25rem;
transition: font-size 0.1s ease-in-out, top 0.1s ease-in-out;
}
label.floating-label input:placeholder-shown {
padding-top: 0;
font-size: 1em;
}
label.floating-label input:placeholder-shown+span {
top: 0.3em;
font-size: 1em;
}
<fieldset>
<legend>
Floating labels example (no-JS)
</legend>
<label class="floating-label">
<input type="text" placeholder=" ">
<span>Username</span>
</label>
<label class="floating-label">
<input type="Password" placeholder=" ">
<span>Password</span>
</label>
</fieldset>
<p>
Inspired by Bootstrap's <a href="https://getbootstrap.com/docs/4.0/examples/floating-labels/">floating labels</a>.
</p>
Estou surpreso com as respostas que temos atributo claro para obter caixas de entrada vazias, dê uma olhada neste código
/*empty input*/
input:empty{
border-color: red;
}
/*input with value*/
input:not(:empty){
border-color: black;
}
ATUALIZAR
input, select, textarea {
border-color: @green;
&:empty {
border-color: @red;
}
}
Mais para ter uma ótima aparência na validação
input, select, textarea {
&[aria-invalid="true"] {
border-color: amber !important;
}
&[aria-invalid="false"], &.valid {
border-color: green !important;
}
}
:empty
aplica-se apenas a elementos que não têm filhos. As entradas não podem ter nós filhos, portanto sua entrada estará sempre com borda vermelha. Veja também este comentário
value
não altera o número de nós filhos.
<parent><child></child></parent>
). Você apenas tem <input></input>
e enquanto você digita o que está mudando não é um <value>
interior nó <input>
, mas um valor atributo :<input value='stuff you type'></input>
Sei que esse é um tópico muito antigo, mas as coisas mudaram um pouco desde então e isso me ajudou a encontrar a combinação certa de coisas necessárias para resolver o problema. Então pensei em compartilhar o que fiz.
O problema era que eu tinha o mesmo css aplicado a uma entrada opcional se ela fosse preenchida, como solicitava para uma entrada preenchida. O css usou a classe psuedo: valid, que aplicou o css na entrada opcional também quando não foi preenchida.
Foi assim que eu consertei;
HTML
<input type="text" required="required">
<input type="text" placeholder="">
CSS
input:required:valid {
....
}
input:optional::not(:placeholder-shown){
....
}