<h1>JS-Less Floaty Labels</h1>
<div class="inputs">

<label class="input">
  <input class="input__field" type="email" placeholder="somoething" value="" />
  <span class="input__label">Some fancy label man</span>
  <span class="input__error">Something went horribly wrong</span>
  <span class="input__info">Sometimes there is something here</span>
</label>
<label class="input">
  <input required class="input__field" type="text" placeholder=" " value="" />
  <span class="input__label">Some dancy label man</span>
</label>
<label class="input">
  <input class="input__field" type="text" placeholder=" " value="Has a value already" />
  <span class="input__label">Some dancy label man</span>
</label>
  
</div>

<p>The JS is only needed for MS Edge (as long as its not Chromeium yet)</p>
@import url('https://rsms.me/inter/inter.css');

:root, input {
  --font: 'Inter var', sans-serif;
  font-family: var(--font);
  font-feature-settings: "dlig" 0, "numr" 0, "dnom" 0, "tnum" , "case" 0, "zero" 0, "frac", "sups" 0, "subs" 0, "cpsp" 0, "salt" 0, "ss01", "ss02" 0, "cv01" 0, "cv02" 0, "cv03" 0, "cv04" 0, "cv05" 0, "cv06" 0, "cv07" 0, "cv08" 0, "cv09" 0, "cv10" 0, "calt", "liga", "kern";
}

:root {
  padding: 1rem;
}

p {
  margin-top: 4rem;
}

.inputs {
  --size-inline: 1rem;
  
  display: flex;
  flex-wrap: wrap;
  margin-left: calc(var(--size-inline) * -1);
  
  & > .input {
    flex: 1 0 calc(50% - var(--size-inline));
    margin-left: var(--size-inline);
    width: 50%;
  }
}

.input {
  --size-bezel-top: 1.4rem;
  --size-bezel: .4rem;
  
  
  --color-bg: transparent;
  --color-bg--active: #aaf0d1;
  
  position: relative;
  display: block;
  
  background: var(--color-bg);
  margin-top: 1rem;
  &__field {
    opacity: 0;
    display: block;
    width: 100%;
    box-sizing: border-box;
    border: none;
    background: transparent;
    
    padding: var(--size-bezel-top) var(--size-bezel) var(--size-bezel);
    box-shadow: 0 .2rem 0 0 #000;
    
    transition: 200ms opacity ease-out;
    &:focus {
      background: var(--color-bg--active);
    }
    &:not(:placeholder-shown),
    .placeHolderNotSown,
    &:focus {
      opacity: 1;
      transition: 200ms opacity ease-out 100ms;
      outline: none;
    }
    &:not(:placeholder-shown) + .input__label,
    .placeHolderNotSown + .input__label,
    &:focus + .input__label {
      transform: scale(.8) translateY(-50%);
    }
    
    &:invalid:not(:placeholder-shown),
    .placeHolderNotSown:invalid {
      & + .input__label + .input__error {
        display: block;
      }
    }
  }
  &__label {
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    box-sizing: border-box;
    padding: var(--size-bezel-top) var(--size-bezel) var(--size-bezel);
    transform-origin: 0 50%;
    transition: 200ms transform ease-out;
  }
  &__error,
  &__info {
    display: block;
    padding: calc(2 * var(--size-bezel)) var(--size-bezel);
    font-size: .6em;
  }
  &__error {
    display: none;
    background: red;
    color: #fff;
  }
}
View Compiled
// edge fallback, works without it in IE11

function checkIfEmpty (e) {
  const $target = e.target;
  
  if ($target.value) {
    $target.classList.remove('placeHolderNotSown');
  } else {
    $target.classList.add('placeHolderNotSown');
  }
}

document.addEventListener('focus', checkIfEmpty, true);
document.addEventListener('blur', checkIfEmpty, true);
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.