1

The end goal is to move the label upon focus of the input field (like the material design inputs). In chrome, the fiddle works flawlessly.

<div class="row">
    <div 
        style="position: relative;">
        <div class="col-sm-12">
            <span class="fancy-wrapper">
                <input
                    name="name" type="text"
                    class="form-control &Control/class; login-input" 
                    />
                <label for="name" class="control-label login-label">
                    <span>a label</span>
                </label>
            </span>
        </div>
    </div>
</div>
.login-label {
  position: absolute;
  pointer-events: none;
  top: 12px;
  left: 30px;
  transition: 0.2s ease all;
  -moz-transition: 0.2s ease all;
  -webkit-transition: 0.2s ease all;
}

.login-input {
  height: 44px;
}

.login-input:focus {
  border-color: #ccc;
  box-shadow: none;
}

.fancy-wrapper > .login-input:focus ~ .login-label,
.fancy-wrapper > .login-input:valid ~ .login-label,
.fancy-wrapper > .login-input:-webkit-autofill ~ .login-label,
.fancy-wrapper > .login-input:focus ~ .control-label,
.fancy-wrapper > .login-input:valid ~ .control-label,
.fancy-wrapper > .login-input:-webkit-autofill ~ .control-label,
.fancy-wrapper > .login-input:focus ~ label,
.fancy-wrapper > .login-input:valid ~ label,
.fancy-wrapper > .login-input:-webkit-autofill ~ label,
.fancy-wrapper > .login-input:focus + *,
.fancy-wrapper > .login-input:valid + *,
.fancy-wrapper > .login-input:-webkit-autofill + *,
.fancy-wrapper > .login-input:focus + *,
.fancy-wrapper > .login-input:valid + *,
.fancy-wrapper > .login-input:-webkit-autofill + *,
.fancy-wrapper > .login-input:focus + *,
.fancy-wrapper > .login-input:valid + *,
.fancy-wrapper > .login-input:-webkit-autofill + *  {
  top: -10px;
  left: 29px;
  background-color: #fff;
  padding: 1px 4px;
  border-radius: 4px;
  margin-top: -2px;
}

https://jsfiddle.net/5tk70Ljx/

Chasen Bettinger
  • 7,194
  • 2
  • 14
  • 30
  • What problem are you trying to solve with the `-webkit-autofill`? That's probably not a great way to target an element. Since the `input:valid` would theoretically give you the same thing... – Bryce Howitson Oct 01 '19 at 22:19

2 Answers2

1

Let's start with the fact that all those duplicate rules are overriding each other and you don't need them. Second, -webkit-autofill is only supported by SOME webkit browsers. Firefox is based on the Mozilla rendering engine so it's obviously not going to work. I would guess that Firefox hits that and ignores everything else.

The much easier solution to what you want is just using the adjacent sybling selector. AKA the Plus sign.

.myInputWrap {
    margin: 20px;
    position: relative;
    font-size: 14px;
    font-family: sans-serif;
}
input {
    padding: 2px;
    line-height: 1;
}
label {
    position: absolute;
    top:0; right:0; bottom:0; left:0;
    padding: 2px;
    line-height: 1;
    pointer-events: none;
    transition: transform 0.25s ease-in-out;
}
label span {
    background: white;
    display:inline-block;
    margin-left:2px;
    margin-top: 2px;
    color: #ddd;
}

input:focus + label,
input:valid + label{
    transform: translateY(-10px);
}
<div class="myInputWrap">
 <input type="text" required >
 <label for="">
  <span>Your Name</span>
 </label>
</div>

You'll need to play with positioning to get the label to start and end where you want it to. I added a span with a white background to make it look like the border gets hidden. You could simply place higher up and then not worry about a fake mask over the line.

Bryce Howitson
  • 7,339
  • 18
  • 40
  • Yup, the `-webkit-autofill` was the problem. I fixed it by only enabling that on chrome browsers. – Chasen Bettinger Oct 01 '19 at 22:15
  • The problem is a problem because of the engine I'm building on.. but in Chrome (and I assume other webkit browsers), when the browser autofills values inside the input box, input:valid isn't triggered until the user actually clicks on the page. With -webkit-autofill, when the page loads and the browser autofills values, the labels move. – Chasen Bettinger Oct 01 '19 at 22:20
  • 1
    @ChasenBettinger that makes sense but I'd be leary about relying on a browser to do that for you. I'd suggest adding `autocomplete="off"` to the HTML input and then injecting the correct string into the input value. – Bryce Howitson Oct 01 '19 at 22:23
  • Yeah you're right. Although, it's much easier said than done with the engine I'm using unfortunately. – Chasen Bettinger Oct 01 '19 at 22:25
  • @ChasenBettinger does the browser autofill trigger a javascript event? like `onChange`? If so you could add a css class to the input wrapper eg: `.filled input+label {}` That *might* be more cross-browser friendly too. My browser doesn't pre-fill anything so I have literally no idea how to try it. – Bryce Howitson Oct 01 '19 at 22:32
  • @ChasenBettinger there's some stuff in [here](https://stackoverflow.com/questions/11708092/detecting-browser-autofill) that might help you. – Bryce Howitson Oct 01 '19 at 22:35
  • Yup, spent some time reading that before I got to `webkit-autofill` – Chasen Bettinger Oct 01 '19 at 22:36
  • 1
    @ChasenBettinger I would probably lean more toward some of the javascript solutions if you can. Relying on that kind of thing in CSS is going to cause headaches (even Can I Use cautions against it) – Bryce Howitson Oct 01 '19 at 22:39
0

I can't validate why, but this works if -webkit-autofill is not used in the selector.

Chasen Bettinger
  • 7,194
  • 2
  • 14
  • 30