Input attribute required is affecting css transition

Viewed 609

I have some inputs styled by CSS and on one input I need to remove the attribute required. For some reason, this changes how the CSS animations behave. When the attribute required is added to an input, it changes the way the animations behave.

Any solution?

HTML

<input type="text" class="form-input" autofocus required>
<span class="highlight"></span>
<span class="bar"></span>
<label class="form-label">Name</label>

<input type="text" class="form-input" autofocus>
<span class="highlight"></span>
<span class="bar"></span>
<label class="form-label">Name</label>

CSS

body {
  background-color:#fff;
  padding:40px;
}

.group            { 
  position:relative; 
  margin-bottom:45px; 
}
.form-input                 {
  font-size:18px;
  padding:10px 10px 10px 5px;
  display:block;
  width:100%;
  border:none;
  border-bottom:1px solid #757575;
}
.form-input:focus       { outline:none; }

/* LABEL ======================================= */
.form-label                  {
  color:#999; 
  font-size:18px;
  font-weight:normal;
  position:absolute;
  pointer-events:none;
  left:5px;
  top:10px;
  transition:0.2s ease all; 
  -moz-transition:0.2s ease all; 
  -webkit-transition:0.2s ease all;
}

/* active state */
.form-input:focus ~ .form-label, .form-input:valid ~ .form-label        {
  top:-20px;
  font-size:14px;
  color:#d438c5;
}

/* BOTTOM BARS ================================= */
.bar    { position:relative; display:block; width:100%; }
.bar:before, .bar:after     {
  content:'';
  height:2px; 
  width:0;
  bottom:1px; 
  position:absolute;
  background:#d438c5; 
  transition:0.2s ease all; 
  -moz-transition:0.2s ease all; 
  -webkit-transition:0.2s ease all;
}
.bar:before {
  left:50%;
}
.bar:after {
  right:50%; 
}

/* active state */
.form-input:focus ~ .bar:before, .form-input:focus ~ .bar:after {
  width:50%;
}

/* HIGHLIGHTER ================================== */
.highlight {
  position:absolute;
  height:60%; 
  width:100px; 
  top:25%; 
  left:0;
  pointer-events:none;
  opacity:0.5;
}

/* active state */
.form-input:focus ~ .highlight {
  -webkit-animation:inputHighlighter 0.3s ease;
  -moz-animation:inputHighlighter 0.3s ease;
  animation:inputHighlighter 0.3s ease;
}

.form-select {
    height: 47px;
    background: transparent;
}

/* ANIMATIONS ================ */
@-webkit-keyframes inputHighlighter {
    from { background:#d438c5; }
  to    { width:0; background:transparent; }
}
@-moz-keyframes inputHighlighter {
    from { background:#d438c5; }
  to    { width:0; background:transparent; }
}
@keyframes inputHighlighter {
    from { background:#d438c5; }
  to    { width:0; background:transparent; }
}

Take a look at my js fiddle. https://jsfiddle.net/97892awh/

3 Answers

That happens because of this selector:

.form-input:valid ~ .form-label

As you can see you have a :valid selector, which is triggered when the input is valid (obviously), in your case, when the input is required. Remove that and it will work:

.form-input:focus ~ .form-label{
  top:-20px;
  font-size:14px;
  color:#d438c5;
}

Example on jsFiddle.

Just remove the valid selector in your css if you don't want different css.

/* active state */
.form-input:focus ~ .form-label, .form-input:valid ~ .form-label {
  top:-20px;
  font-size:14px;
  color:#d438c5;
}

Here is how I solved it.

Added a CSS class

.not-empty {
  top:-20px;
  font-size:14px;
  color:#d438c5;
}

And some jquery

$('#name').focusout(function() {
    var val = this.value;
  if (val.length > 0) {
    $('#name-label').addClass('not-empty');
  } else {
    $('#name-label').removeClass('not-empty');
  }
});

And also edited the HTML like this

<div class="group">
  <input type="text" class="form-input" id="name" autofocus>
  <span class="highlight"></span>
  <span class="bar"></span>
  <label class="form-label" id="name-label">Name</label>
</div>

https://jsfiddle.net/97892awh/3/

Related