Search code examples
htmlcsspseudo-class

Floating Labels with CSS not working when input type is set to Email


I'm having an input textbox when we type something the label floats to the top. it works fine when the input type is "text" but if the input textbox is set to type "Email" it stops working, I need a solution to make it work.

.relPos {
  position: relative;
}

.upLabel {
  position: absolute;
  top: 0px;
  left: 0;
  transition: .3s;
  pointer-events: none;
}

.upInputs input {
  box-shadow: none;
}

.upInputs input:focus~.upLabel,
.upInputs input:valid~.upLabel {
  top: -15px;
  border: none;
}
<br>
<div class="relPos upInputs">
  <input type="text" required>
  <label class="upLabel">Type="Text"</label>
</div>
<br>
<div class="relPos upInputs">
  <input type="email" required>
  <label class="upLabel">Type="Email"</label>
</div>

<br>


Solution

  • :valid will only get triggered when the input is valid so you need an email (xxx@yyy.zz) for it to work. Instead, you can consider using :placeholder-shown ref and have a empty placeholder:

    .relPos {
      position: relative;
    }
    
    .upLabel {
      position: absolute;
      top: 0px;
      left: 0;
      transition: .3s;
      pointer-events: none;
    }
    
    .upInputs input {
      box-shadow: none;
    }
    
    .upInputs input:focus~.upLabel,
    .upInputs input:not(:placeholder-shown)~.upLabel {
      top: -15px;
      border: none;
    }
    <br>
    <div class="relPos upInputs">
      <input type="text" required placeholder=" ">
      <label class="upLabel">Type="Text"</label>
    </div>
    <br>
    <div class="relPos upInputs">
      <input type="email" required placeholder=" ">
      <label class="upLabel">Type="Email"</label>
    </div>
    
    <br>

    To illustrate the issue with :valid

    .relPos {
      position: relative;
    }
    
    .upLabel {
      position: absolute;
      top: 0px;
      left: 0;
      transition: .3s;
      pointer-events: none;
    }
    
    .upInputs input {
      box-shadow: none;
    }
    
    .upInputs input:valid~.upLabel {
      top: -15px;
      border: none;
    }
    <div class="relPos upInputs">
      <input type="email" required value="not an email">
      <label class="upLabel">Type="Email"</label>
    </div>
    <br>
    <div class="relPos upInputs">
      <input type="email" required value="example@email.com">
      <label class="upLabel">Type="Email"</label>
    </div>