Search code examples
htmlgoogle-chromeautofill

Why is Chrome autofilling account email in wrong input element?


My issue happens in the following HTML document:

<!doctype html>

Search: <input type="search">

<!-- Display is none when logged in -->
<div style="display: none">
    Login:<br>
    <input type="email">
    <input type="password">
</div>

When I'm signed out, the mail/password elements are visible and they get auto-filled correctly. After I'm logged in, the page loads again but now the login inputs are hidden hidden, for some reason it then auto-fills the search element with my email address.

When I reveal the login elements using the developer tools, it looks like this:

enter image description here

So it's auto-filling hidden elements (which I'm OK with), but for some reason it puts my email address in the wrong field! How can I stop Chrome from doing this?


Solution

  • This issue is caused by a 'quirk' in Chrome's auto-filling behaviour.

    Different websites construct their login elements in different ways, so Chrome has to use a set of heuristics to try to understand login forms. Unfortunately this doesn't always work correctly.

    How Chrome determines the credential fields

    This is what Chrome is doing to find the login fields:

    1. It finds a password element, now Chrome needs to find the accompanying username element.
    2. To find the username/email element, Chrome scans through some of the elements above the password element.
    3. It selects the element with the highest 'interactability' rating that's nearest to the password field.

    Since the email element is hidden it gets a worse interactability score than the search element, so Chrome picks the search element.

    Fix

    The fix for the issue is simple, you can restrict what elements Chrome will consider to be the username by wrapping those elements in a form. In this case you can just replace the div.

    <!doctype html>
    
    Search: <input type="search">
    
    <!-- Display is none when logged in -->
    <form style="display: none">
        Login:<br>
        <input type="email">
        <input type="password">
    </form>
    

    Chrome will not look outside of the form for the username field, so it always picks the correct element.

    Nowadays I always put input elements that belong together inside of a form, even when I don't actually use the form for anything and instead handle the input with JavaScript. It still helps browsers, plugins, and screen readers make better sense of your site.