Matching an empty input box using CSS

Viewed 149579

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:

input[value=""]
15 Answers

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

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

<style>
input[value=""].product {
    display: none;
}
</style>

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

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>

Related