input:not(:placeholder-shown) ~ label selector does not work with autofill
Asked Answered
W

3

17

I have floating placeholder in the input field.

Placeholder will appear in center when we input value has not been provided. as shown in the below screenshot (Email and password is placeholder).

enter image description here

Now when you provide the value to email it does look like below. Observer the Email and password has been pulled up when value has been provided

enter image description here

The problem occurs when browser starts auto-filling/autocomplete this value from the saved credentials on page load like username, email, password so on. see the screen shot below:

enter image description here

css

:root {
  --input-padding-x: .75rem;
  --input-padding-y: .75rem;
}

html,
body {
  height: 100%;
}

.form-signin {
  width: 100%;
  max-width: 600px;
  padding: 15px;
  margin: auto;
  padding-top: 40px;
  padding-bottom: 40px;
}

.form-label-group {
  position: relative;
  margin-bottom: 1rem;
}

.form-label-group > input,
.form-label-group > label {
  padding: var(--input-padding-y) var(--input-padding-x);
}

.form-label-group > label {
  position: absolute;
  top: 0;
  left: 0;
  display: block;
  width: 100%;
  margin-bottom: 0; /* Override default `<label>` margin */
  line-height: 1.5;
  color: #495057;
  border: 1px solid transparent;
  border-radius: .25rem;
  transition: all .1s ease-in-out;
}

.form-label-group input::-webkit-input-placeholder {
  color: transparent;
}

.form-label-group input:-ms-input-placeholder {
  color: transparent;
}

.form-label-group input::-ms-input-placeholder {
  color: transparent;
}

.form-label-group input::-moz-placeholder {
  color: transparent;
}

.form-label-group input::placeholder {
  color: transparent;
}

.form-label-group input:not(:placeholder-shown) {
  padding-top: calc(var(--input-padding-y) + var(--input-padding-y) * (2 / 3));
  padding-bottom: calc(var(--input-padding-y) / 3);
}

.form-label-group input:not(:placeholder-shown) ~ label {
  padding-top: calc(var(--input-padding-y) / 3);
  padding-bottom: calc(var(--input-padding-y) / 3);
  font-size: 12px;
  color: #777;
}

HTML

<form class="form-signin">
    <h1 class="h3 mb-3 font-weight-normal">Please Type new password</h1>
    <div class="form-label-group">
        <input type="text" id="inputEmail" [(ngModel)]="email" name="email" class="form-control" placeholder="Email" required=""
            autofocus="">
        <label for="inputEmail">Email</label>
    </div>

    <div class="form-label-group">
        <input type="password" id="inputPassword" [(ngModel)]="password" name="password" class="form-control" placeholder="Password"
            required="">
        <label for="inputPassword">Password</label>
    </div>

    <div class="row">
      <div class="col-sm-6">
        <button class="btn btn-lg btn-primary btn-block" (click)="onSubmit()" type="button">Change password</button>
      </div>
    </div>
</form>

I had already tried to autofocus on the email field but that did not worked. I also tried to click the element from the code after the page load but with no luck. Please help me how do I fix this.

Whidah answered 30/3, 2019 at 3:51 Comment(0)
A
24

It works for me

.form-label-group input:-webkit-autofill ~ label {
        /* CSS property  */
}

You can try it

Alvinaalvine answered 25/4, 2019 at 3:1 Comment(1)
Thanks for the tip on :-webkit-autofill, that's just what I was missing!Molybdenite
M
14

I had the same problem. In my form, I'm using the following selectors to move my label text out of the way, on any of these 3 conditions:

  1. :focus (so it's not in the way of the cursor when focused)
  2. :not(:placeholder-shown) (indicating "the input is not empty")
  3. :-webkit-autofill (because 2 wasn't triggering on page refresh / autofill)

The SCSS combination is:

input {
  &:focus, &:not(:placeholder-shown), &:-webkit-autofill {
    &+label { /* Move your label */ }
  }
}

(Note that you also need a placeholder=" " on your input.)

Here's a live example: https://codepen.io/jeffward/pen/ZdBxXd

Molybdenite answered 19/6, 2019 at 20:41 Comment(2)
Works fine in Chrome, not in FF. I couldn't find any alternative.Hemicycle
Indeed, stupid FireFox. There is a very old, outstanding feature request for :-moz-autofill bugzilla.mozilla.org/show_bug.cgi?id=740979 Although :autofill wouldn't even be necessary if :placeholder-shown worked correctly when auto-filled. :PMolybdenite
P
2

Add placeholder=" " to the input Element.

Permian answered 9/5, 2023 at 19:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.