How do I apply a style to an empty input field? If the user types something in the input field, the style should no longer be applied. Is this possible in CSS? I tried this:
input[value=""]
In modern browsers you can use :placeholder-shown to target the empty input (not to be confused with ::placeholder).
input:placeholder-shown {
border: 1px solid red; /* Red border only if the input is empty */
}
In HTML you must set the placeholder attribute. Chrome browser requires at least a space character as value.
<input type="text" placeholder=" "> <!-- Do not remove placeholder -->
If only the field is required you could go with input: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>
See live on jsFiddle
OR negate using #foo-thing:invalid (credit to @SamGoody)
input[value=""], input:not([value])
works with:
<input type="text" />
<input type="text" value="" />
But the style will not change as soon as someone will start typing (you need JS for that).
Updating the value of a field does not update its value attribute in the DOM so that's why your selector is always matching a field, even when it's not actually empty.
Instead use the invalid pseudo-class to achieve what you want, like so:
input:required {
border: 1px solid green;
}
input:required:invalid {
border: 1px solid red;
}
<input required type="text" value="">
<input required type="text" value="Value">
I realize this is a very old thread, but things have changed a bit since and it did help me find the right combination of things I needed to get my problem fixed. So I thought I'd share what I did.
The problem was I needed to have the same css applied for an optional input if it was filled, as I had for a filled required. The css used the psuedo class :valid which applied the css on the optional input also when not filled.
This is how I fixed it;
HTML
<input type="text" required="required">
<input type="text" placeholder="">
CSS
input:required:valid {
....
}
input:optional::not(:placeholder-shown){
....
}
If supporting legacy browsers is not needed, you could use a combination of required, valid, and invalid.
The good thing about using this is the valid and invalid pseudo-elements work well with the type attributes of input fields. For example:
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="[email protected]" required />
<input type="url" name="website" placeholder="http://johndoe.com"/>
<input type="text" name="name" placeholder="John Doe" required/>
For reference, JSFiddle here: http://jsfiddle.net/0sf6m46j/
This worked for me:
For the HTML, add the required attribute to the input element
<input class="my-input-element" type="text" placeholder="" required />
For the CSS, use the :invalid selector to target the empty input
input.my-input-element:invalid {
}
Notes:
required from w3Schools.com:
"When present, it specifies that an input field must be filled out before submitting the form."$('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');
}
});
in jQuery. I added a class and styled with css.
.empty { background:none; }
This question might have been asked some time ago, but as I recently landed on this topic looking for client-side form validation, and as the :placeholder-shown support is getting better, I thought the following might help others.
Using Berend idea of using this CSS4 pseudo-class, I was able to create a form validation only triggered after the user is finished filling it.
Here is ademo and explanation on CodePen: https://codepen.io/johanmouchet/pen/PKNxKQ
If you're happy not not supporting IE or pre-Chromium Edge (which might be fine if you are using this for progressive enhancement), you can use :placeholder-shown as Berend has said. Note that for Chrome and Safari you actually need a non-empty placeholder for this to work, though a space works.
*,
::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>
So I was playing around earlier with the new :where and :is clauses and conceived of this bit of fun, and after finding this post with the :invalid and :placeholder-shown bits, thought I might share this possibility for future reference
:required:where( input, textarea ):where( :placeholder-shown, :invalid ) {
border-color: var(--warning);
}
which applies the :root { --warning: orange; } color to any required input or textarea, that is either empty or invalid. And that is just downright sexy
While no browser currently (2021-10-01) supports it, there is a proposal for a :blank pseudo-class.
ref: https://developer.mozilla.org/en-US/docs/Web/CSS/:blank. Do note, this is experimental, and no browser supports it as of now.
This is how you can make it possible. don't forget to set placeholder=" " and required attr to your inputs. you can change the props as you wish.
body{
display: flex;
justify-content: center;
align-items: center;
}
.input-gp {
margin-top: 150px;
position: relative;
}
.input-gp input {
position: relative;
}
.input-gp label{
position: absolute;
left: 5px;
bottom: 5px;
transition: all .4s ease;
}
.input-gp input:placeholder-shown + label{
left: 10px;
bottom: 5px;
}
.input-gp input:focus + label,
.input-gp input + label{
bottom: 30px;
left: 10px;
}
<body>
<div class="input-gp ">
<input type="email" name="" id="email" placeholder=" " required>
<label class=" position-absolute" for="email"> Email</label>
</div>
</body>
I'm wondered by answers we have clear attribute to get empty input boxes, take a look at this code
/*empty input*/
input:empty{
border-color: red;
}
/*input with value*/
input:not(:empty){
border-color: black;
}
UPDATE
input, select, textarea {
border-color: @green;
&:empty {
border-color: @red;
}
}
More over for having a great look in the validation
input, select, textarea {
&[aria-invalid="true"] {
border-color: amber !important;
}
&[aria-invalid="false"], &.valid {
border-color: green !important;
}
}
:empty applies only to elements that have no children. Inputs can't have child nodes at all so your input will be always with red border. Also see this commentvalue doesn't change the number of child nodes.<parent><child></child></parent>). You just have <input></input> and as you type what's changing is not a <value> node inside <input> but a value attribute: <input value='stuff you type'></input>