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:
- It finds a password element, now Chrome needs to find the accompanying username element.
- To find the username/email element, Chrome scans through some of the elements above the password element.
- 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.