How do I apply a style to an empty input box? If the user types something in the input field, the style should no longer be applied. Is this possible in CSS? I tried this:


Solution 1

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 */

More info and browser support:

Solution 2

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)

Solution 3

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">

Solution 4

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).

Solution 5

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=""/>
<input type="text" name="name" placeholder="John Doe" required/>

For reference, JSFiddle here:

Solution 6

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 {



  • About required from "When present, it specifies that an input field must be filled out before submitting the form."

Solution 7

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;


<input type="text" required="required">
<input type="text" placeholder="">


input:required:valid {

Solution 8

    tmpval = $(this).val();
    if(tmpval == '') {
    } else {

in jQuery. I added a class and styled with css.

.empty { background:none; }

Solution 9

It worked for me to add a class name to the input and then apply CSS rules to that:

<input type="text" name="product" class="product" />

input[value=""].product {
    display: none;

Solution 10

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.

 ::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;
    Floating labels example (no-JS)
  <label class="floating-label">
    <input type="text" placeholder=" ">
  <label class="floating-label">
    <input type="Password" placeholder=" ">
  Inspired by Bootstrap's <a href="">floating labels</a>.

Solution 11

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:

Solution 12

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

Solution 13

While no browser currently (2021-10-01) supports it, there is a proposal for a :blank pseudo-class.

ref: Do note, this is experimental, and no browser supports it as of now.

Solution 14

I'm wondered by answers we have clear attribute to get empty input boxes, take a look at this code

/*empty input*/
    border-color: red;
/*input with value*/
    border-color: black;


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;