Browser autofill suggestion box overlapping floating label input field

1.1k views Asked by At

I have a form design with a floating label and an issue with Edge and Chrome autofill suggestion box. After a click on the input field, it moves down 30px (margin-top) to make place for the label.
The issue is that the autofill suggestion select box does NOT move down those 30px, and it overlays the input field (full code).

example

When I click again in the input field, it moves down accordingly like I want it.

click again

Now my question: Is it possible to move the browser suggestion box down alongside the input or maybe simulate a second focus on the input to refresh the autofill box location.

Edit

The suggestion box is not part of the DOM content, so I can't change it directly. That is not surprising.
What I'm asking is if there is any known workaround to make it move to the right place after my input has done its animation. Floating labels are quite common, am I the first one confronted with this issue?
The location of the suggestion box just needs to be refreshed, a second manual click in the input field works, but is there really NO clean automated way?

If there is really not, I clearly see this as a browser bug, as the suggestion box is flat out on the wrong spot. Is there maybe an issue open already for the browsers, asking they put the suggestion box right below (or above) the input fields ALSO when they move? Wouldn't it make sense to "follow" the input field?

1

There are 1 answers

5
Jeffhowcodes On

My autocomplete suggestions only pop up when the inputs have the name attribute. That made me wonder if I could trigger it after the transitionend by injecting the name attribute (using the label's htmlFor attribute). It works, but requires a second click to trigger the suggestions.

I know this isn't a perfect answer but hope it gets someone closer to a better workaround.

const inputgroups = document.querySelectorAll('.form-input-group');

inputgroups.forEach( inputgroup => {
  inputgroup.addEventListener('transitionend', (e) => {
    if(e.propertyName === "transform") {
      const input = e.target.previousElementSibling
      label = e.target.htmlFor
      if(input.name) {
        input.name = '';
        input.autocomplete = '';
      } else {
        input.name=label;
        input.autocomplete= label;
      }
    }
  })
})
.form-input-group input:valid~label {
  transform: translate(0, -200%);
}

.form-input-group input:valid {
  margin-top: 30px;
}

.form-input-group input:focus~label {
  transform: translate(0, -200%);
}

.form-input-group input:focus {
  outline: none;
  background: #ff4a56;
  color: white;
  margin-top: 30px;
}

.form-input-group label,
.form-input-group input {
  transition: all 0.25s cubic-bezier(0.53, 0.01, 0.35, 1.5);
}

.form-input-group {
  position: relative;
  padding: 10px 0;
}

.form-input-group:first-of-type {
  padding-top: 0;
}

.form-input-group:last-of-type {
  padding-bottom: 0;
}

.form-input-group label {
  transform-origin: left center;
  color: #ff4a56;
  font-weight: 100;
  letter-spacing: 0.01em;
  font-size: 17px;
  box-sizing: border-box;
  padding: 10px 15px;
  display: block;
  position: absolute;
  transform: translate(0, -100%);
  z-index: 2;
  pointer-events: none;
}

.form-input-group input {
  appearance: none;
  background-color: none;
  border: 1px solid #ff4a56;
  line-height: 0;
  font-size: 17px;
  width: 100%;
  display: block;
  box-sizing: border-box;
  padding: 10px 15px;
  border-radius: 60px;
  color: #ff4a56;
  font-weight: 100;
  letter-spacing: 0.01em;
  position: relative;
  z-index: 1;
}
<form action="" method="get">
  <div class="form-input-group">
    <input type="text" required/>
    <label for="given-name">First Name</label>
  </div>
  <div class="form-input-group">
    <input type="text" required/>
    <label for="family-name">Last Name</label>
  </div>
  <div class="form-input-group">
    <input type="text" required/>
    <label for="email">Email Address</label>
  </div>
  <div class="form-input-group">
    <input type="password" required/>
    <label>Email Confirm</label>
  </div>
</form>