When trying to create a login form with outlined
text fields in Vutify, the chrome autocomplete overlap with labels
,
<v-text-field
v-model="email"
label="e-mail"
name="email"
outlined
prepend-icon="mdi-account"
type="text"
required
>
</v-text-field>
you can regeneare here please fill and submit, then go back.
This is how I have fixed this issue.
It seems our main problems are the following:
It's interesting to see any click from the browser window FROM USER automatically inform reactivity and all work fine again but it's not work FROM trigger/dispatch internal way.
So first, we need to find a way to react after login/password autofill. And second, we need to fix ourself the design because only a FROM USER action made the design work fine again.
1. React after autofilling at loading page
:-webkit-autofill
at regular interval while X second after code was mounted to see if an autofilling was injected (work fine for Chrome/Firefox/Edge from my test)animationstart
event (see here: https://github.com/material-components/material-components-web/issues/4447#issuecomment-580401216)I use the first solution:
export default {
//...
data() {
return {
//...
autofillFix: false,
}
},
//...
mounted() {
this.autoLoginCheckingInterface()
},
//...
autoLoginCheckingInterface() {
// each 100ms we check if the issue was produced
let intervalDetectAutofill = setInterval(() => {
if (
// we target at least one of the stuff that will be affected by autofill
// to do our checking
document.querySelectorAll('input[type="password"]:-webkit-autofill')
.length > 0
) {
// and we inform the system about the issue if it is produced
this.autofillFix = true
// we stop to check if issue was produced
clearInterval(intervalDetectAutofill)
}
}, 100)
// if after 3s nothing appear, means no autofill was made
setTimeout(() => {
if (intervalDetectAutofill) {
clearInterval(intervalDetectAutofill)
intervalDetectAutofill = null
}
}, 3000)
},
//...
}
<!--
we will inject `.autofill-fix` class to be able fix design ourself at time of this bug occur
-->
<v-text-field
...
:class="{ 'autofill-fix': autofillFix }"
...
label="Email address or username"
...
dense
outlined
@focus="autofillFix = false"
/>
<!--
we use @focus to let the normal behavior take again the lead
because we know this USER ACTION will made Chrome work well again
-->
<v-text-field
...
:class="{ 'autofill-fix': autofillFix }"
...
label="Password"
type="password"
...
dense
outlined
@focus="autofillFix = false"
/>
2. Fix ourself the design
We can see what are the change when v-text-field
is filled. Without content, we can see this:
And after autofilling, we can see this:
So from the red part, we can see the following code need to be injected at time
of .autofill-fix
presence to fix the design in the proper way
.autofill-fix.v-text-field--outlined.v-input--dense .v-label {
left: -28px!important;
transform: translateY(-16px) scale(.75);
}
Note: You need change the CSS selector if you not use outlined
or dense
. Be careful about the specificity of selector https://specificity.keegan.st/. In fact, you need adapt the fixed change to your design
Another way is to defined like @elazard suggest here an autofill variable like this
data () {
return {
login: null,
password: null,
autofill: false,
intervalDetectAutofill: null
}
},
<v-text-field
v-model="password"
type="password"
label="Password"
:placeholder="autofill ? ` ` : null"
/>
With the solution given by @adam-reis, in the mounted()
of the login page
mounted () {
// search for autofill every 100ms
this.intervalDetectAutofill = setInterval(() => {
if (document.querySelectorAll("input[type=\"password\"]:-webkit-autofill").length > 0) {
this.autofill = true
}
}, 100)
// clean interval if needed after 3s
setTimeout(() => {
if (this.intervalDetectAutofill) {
clearInterval(this.intervalDetectAutofill)
this.intervalDetectAutofill = null
}
}, 3000)
},
And of course setting autofill to false if user input
watch: {
password () {
this.autofill = false
},
autofill () {
// clean interval if autofill detected or user input
if (this.intervalDetectAutofill) {
clearInterval(this.intervalDetectAutofill)
this.intervalDetectAutofill = null
}
}
},
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With