Raise label css

How do I make the label rise higher when the input or focus is filled, or if the empty one is returned back?

.item-f{
    border-radius: 4px;
    border: 1px solid #DCECF4;
    width: 100%;
    height: 60px;
    position: relative;
}
input{
    border-radius: 4px;
    border: 1px solid #DCECF4;
    color: #81819F;
    font-family: 'Rubik';
    font-weight: 400;
    font-size: 14px;
    padding: 0 15px;
    width: 100%;
    height: 60px;
}
label{
    position: absolute;
    top: 8px;
    font-size: 14px;
    left: 0;
    -webkit-transition: all 0.3s ease;
    transition: all 0.3s ease;
    -webkit-animation-delay: 0s;
    animation-delay: 0s;
}
input:focus + label,
    input:valid + label {
      top: 0px;
    }
<div class="item-f required">
     <input type="text" name="city" value="Серг" class="item-label" id="input-city" />
     <label for="input-city">Имя</label>
</div>

Here's how I try to do

const input = $('.item-label');

    input.addEventListener('.item-label', () => {
        if (input.value !== '') {
            input.classList.add('input_filled');
        } else {
            input.classList.remove('input_filled');
        }
    });

Writes

Uncaught TypeError: input.addEventListener is not a function
Author: Alexandr_TT, 2019-08-06

3 answers

On the knee, I quickly concocted, I think that the logic will be clear to you

const input = document.querySelector('input');

input.addEventListener('input', () => {
  if (input.value !== '') {
    input.classList.add('input_filled');
  } else {
    input.classList.remove('input_filled');
  }
});
form {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

.form-group {
  position: relative;
}

label {
  position: absolute;
  left: 10px;
  top: 0;
  transition: transform .3s ease;
}

input:focus + label, .input_filled + label {
  transform: translateY(-18px);
}
<form action="#">
  <div class="form-group">
    <input id="foo" type="text">
    <label for="foo">Test</label>
  </div>
</form>

UPD.

const inputs = [...document.querySelectorAll('input')];

inputs.forEach(input => {
  input.addEventListener('input', () => {
    if (input.value !== '') {
      input.classList.add('input_filled');
    } else {
      input.classList.remove('input_filled');
    }
  });
});
form {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

.form-group {
  position: relative;
  margin: 25px 0;
}

label {
  position: absolute;
  left: 10px;
  top: 0;
  transition: transform .3s ease;
}

input:focus+label,
.input_filled+label {
  transform: translateY(-18px);
}
<form action="#">
  <div class="form-group">
    <input id="foo1" type="text">
    <label for="foo1">Test</label>
  </div>

  <div class="form-group">
    <input id="foo2" type="text">
    <label for="foo2">Test</label>
  </div>

  <div class="form-group">
    <input id="foo3" type="text">
    <label for="foo3">Test</label>
  </div>
</form>
 4
Author: meine, 2019-08-06 08:44:02

body {
  display: flex;
  justify-content: center;
}

.column {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  margin-top: 100px;
}

.column input {
  outline: none;
  border: none;
  border-bottom: 1px solid #9EA3B4;
  height: 30px;
  font-size: 16px;
  color: #9EA3B4;
  margin: 5px 0;
  width: 280px;
  background: transparent;
}

.column label {
  display: block;
  margin-bottom: 5px;
  color: #9EA3B4;
  transform: translateY(-32px);
  line-height: 16px;
  transition: 0.5s;
  pointer-events: none;
  padding-left: 5px;
}

.column input:focus+label,
.column input:valid+label {
  transform: translateY(-56px);
  font-size: 12px;
  padding: 0;
  color: #2196f3;
}
<div class='column'>
  <input type="text" id='name' pattern='(\S+|(\s*\S+\s*){0,}){0,}' required/>
  <label htmlFor="name">Имя </label>
</div>

If it is necessary that when the input is filled in label was at the top, and the pseudo-class valid will help. Any input value in input type= 'text' will be valid.

P.S. If you have not only input with the text type, but also others, for example, number - my method will not help. Because in this input, the label will only hold when entering numbers

 2
Author: Владислав, 2019-08-06 11:10:41

In your case, the input:valid + label selector rewrites the style of the input selector. leave only input:focus + label

.item-f {
    border-radius: 4px;
    border: 1px solid #DCECF4;
    width: 100%;
    height: 60px;
    position: relative;
}

input {
    border-radius: 4px;
    border: 1px solid #DCECF4;
    color: #81819F;
    font-family: 'Rubik';
    font-weight: 400;
    font-size: 14px;
    padding: 0 15px;
    width: 100%;
    height: 60px;
}

label {
    position: absolute;
    top: 8px;
    font-size: 14px;
    left: 0;
    -webkit-transition: all 0.3s ease;
    transition: all 0.3s ease;
    -webkit-animation-delay: 0s;
    animation-delay: 0s;
}

input:focus + label {
  top: 0px;
}
<div class="item-f required">
     <input type="text" name="city" value="Серг" class="item-label" id="input-city" />
     <label for="input-city">Имя</label>
</div>
 0
Author: Jurij Jazdanov, 2019-08-06 08:27:19