TIL - Autocomplete and forms

This post is more than 2 years old.

As it is Thanksgiving week here in America and my brain has already kinda checked out, I decided to take a quick look at a particular aspect of the input tag - autocomplete.

As you may, or may not know, most modern web browsers will make an attempt to remember form fields of a "similar nature" such that entering your name on one site means that when you go to type in your name on another form it will offer to automatically complete the field for you.

If you don't like this, or perhaps you're using your own autocomplete, you can add autocomplete="off" to either the form tag or to an individual input field. The default behavior (most of the time) is to default to on.

Simple enough. But if you read the spec, you discovered that the autocomplete attribute can also provide a "hint" about what field it is. So for example, maybe you've named your form field f_name, or firName, or usersGiveName, each of which is meant to represent what we commonly consider a first name, you can actually tell the browser to consider each of those variations to be the first name.

The spec includes support for a large number of "hints", including:

  • name (full name)
  • given-name (first name)
  • family-name (last name)
  • honorific-suffix (Mr, Dr, etc)
  • new-password (oh my god don't use this, why would you want to recommend re-using the same password???)
  • address-line1(-3), address-level(-4) (address-level2 is city, of course)
  • country
  • country-name (um)

And so on. If you read the spec closely, it is also supposed to support "grouping", such that I can say this is my street-address for shipping versus billing. So with that in mind, I decided to do a bit of digging. I was curious about a few things:

  • When would the browser prompt me to fill in one field versus an entire form?
  • Can I use crazy field names if I use the right autocomplete value as a hint?
  • What happens if I mix in a datalist in just to be crazy?

So first - a simple form.


simple form:<br/>
<form>
	first name: <input type="text" name="firstname"><br/>	
	last name: <input type="text" name="lastname"><br/>	
	<input type="submit">
</form>

Nothing special about that. On Chrome, once I enter a value once, I will get prompted to autofill the field, but only one field at a time. It didn't remember that last time I did "Raymond" that "Camden" was an associated value.

shot1

Note the lovely pee-yellow CSS Chrome uses to signify an autocomplete field. I honestly don't know why it does this when it requires user action in order to fill. Maybe the thinking is that I'll forget where the name came from? (FYI, apparently you can tweak it: http://stackoverflow.com/questions/2781549/removing-input-background-colour-for-chrome-autocomplete)

Firefox has the same behavior (without the CSS pee) as does MS Edge (but with pee).

Safari lets you use either other forms or your local contact info for form data. You can actually use both if you want:

shot2

However, Safari will not begin suggesting a value until you type one letter. To me, that's a mistake, because at the point I'm typing, I can finish typing my name in less time it takes for Safari to draw a list of names. The UI for filling from a contact card is different from 'regular' autofill:

safari

Ok, how about some more tests. I was first curious about why/when a form would completely fill out. I tried this test:


autocomplete on, with autocomplete hints<br/>
<form>
	first name: <input type="text" name="firstname" autocomplete="given-name"><br/>	
	last name: <input type="text" name="lastname" autocomplete="family-name"><br/>	
	<input type="submit">
</form>
	
<p>

autocomplete hints<br/>
<form>
	first name: <input type="text" name="firstname" autocomplete="given-name"><br/>	
	last name: <input type="text" name="lastname" autocomplete="family-name"><br/>	
	street: <input type="text" name="street" autocomplete="street-address"><br/>
	<input type="submit">
</form>

In Chrome, while I could autocomplete fields in the first form, only the second form let me completely fill the entire form. I'm guessing it is the number of fields that matter here. Again, the UI is slightly different in each case. First, Chrome offering to fill just one field:

shot3

Versus the entire form:

shot4

To be honest, the second screen shot doesn't really imply that it will fill the entire form, but it is certainly different. Maybe the fact that the street address there is supposed to be the clue.

Firefox does not fill out the entire form, but both Safari and Edge filled out the entire form (the one with three fields).

Ok, so what about the autocomplete=X feature? In theory, it should let me provide a clue such that my form field names won't matter. Here was my first test.


autocomplete using hints but weird names
<form autocomplete="on">
	first name: <input type="text" name="firstname2a" autocomplete="given-name"><br/>	
	last name: <input type="text" name="lastname2a" autocomplete="family-name"><br/>	
	<input type="submit">
</form>

In theory, this should work, but it completely failed to note that I've given both names previously. However, all the browsers remembered previous entries when viewing the form again. Then I added another field:


autocomplete using hints but weird names
<form autocomplete="on">
	first name: <input type="text" name="firstname2poo" autocomplete="given-name"><br/>	
	last name: <input type="text" name="lastname2poo" autocomplete="family-name"><br/>	
	street: <input type="text" name="NOTAstreetpoo" autocomplete="street-address"><br/>
	<input type="submit">
</form>

And oddly - Chrome finally got it working right:

Screen Shot 2015-11-23 at 3.12.41 PM

No other browser changed though in terms of its behavior.

Finally - I thought - why not see what happens when you add in a datalist:


autocomplete using hints but weird names and datalist
<form autocomplete="on">
	first name: <input type="text" name="firstname2" autocomplete="given-name" list="names"><br/>	
	<datalist id="names">
		<option>Ray</option>
		<option>Bob</option>
		<option>Elric</option>
	</datalist>
	last name: <input type="text" name="lastname2" autocomplete="family-name"><br/>	
	street: <input type="text" name="NOTAstreet" autocomplete="street-address"><br/>
	<input type="submit">
</form>

I love datalist - and support is good if you ignore Safari (sigh). Firefox and Chrome will render both past entries and autocomplete values at once, which is kinda nice:

ff

Unfortunately, while Edge supports datalist, it doesn't handle rendering autocomplete and the list at the same time - you can see them overlapping here:

shot9

It gets weird if you add more values and the field is towards the bottom of the screen:

shot10

But give it enough space at the bottom and it messes up again:

shot11

I need to remember to file a bug report on this, of course, since I can't expect it to be fixed if I don't bother to report it.

Raymond Camden's Picture

About Raymond Camden

Raymond is a senior developer evangelist for Adobe. He focuses on document services, JavaScript, and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can even buy me a coffee!

Lafayette, LA https://www.raymondcamden.com

Archived Comments

Comment 1 by Šime Vidas posted on 11/25/2015 at 3:10 AM

Regarding new-password, couldn’t it be used as a hint for the browser to offer automatic password generation on that input? I know Safari has such a generator, although I forgot how it can be triggered. Browsers already provide password managers and sync between devices, so password generation would be the final step in handling passwords for the user completely.

Comment 2 by Mem's posted on 11/25/2015 at 10:14 AM

> new-password (oh my god don’t use this, why would you want to recommend re-using the same password???)

I don't understand why you say that. The spec specify: "A new password
(e.g. when creating an account or changing a password)". "New" don't
mean "reuse"?

Comment 3 by Craig Francis posted on 11/25/2015 at 11:00 AM

Šime Vidas, yes Safari does use the `new-password` autocomplete value, and I'm hoping that password managers like 1Password will use it soon as well (https://discussions.agilebi.... This is especially important on password change pages, where you will typically have 3 password fields (old/new/repeat-new).

I'd also like to add that these examples should all use a <label for="XXX"> around the labels, as this does effect the heuristics the browser uses for the guessing-based autocomplete (and is really important for assistive technology / usability / validation).

Comment 4 (In reply to #3) by Raymond Camden posted on 11/25/2015 at 1:41 PM

Thanks for sharing this Craig. From what I see of the spec, https://html.spec.whatwg.or..., new-password doesn't mention anything like this, but I definitely see how it could be used like this. My concern is that it will auto suggest a previous password outside of Safari. I'm going to test.

re: labels - I definitely agree, but does it impact what I'm discussing in this blog post?

Comment 5 (In reply to #3) by Raymond Camden posted on 11/25/2015 at 1:46 PM

Ok, so given this form:

<form autocomplete="on">

new-password, text: <input type="text" name="p1" autocomplete="new-password">

new-password, pword: <input type="password" name="p2" autocomplete="new-password">

<input type="submit">

</form>

Safari did *not* offer to generate a new password for me. Should it have?

Comment 6 (In reply to #3) by Raymond Camden posted on 11/25/2015 at 1:48 PM

Ok, so in Safari preferences, I did *not* have usernames/passwords remembering enabled. When i did that, Safari did try to auto fill the password, but it did not try to generate a new one for me.

Comment 7 (In reply to #2) by Raymond Camden posted on 11/25/2015 at 1:48 PM

My worry is that it would suggest a previous password. It doesn't seem to - so I could be wrong.

Comment 8 (In reply to #3) by Raymond Camden posted on 11/25/2015 at 1:55 PM

Ok, *finally*, I got it working following this:

http://www.macworld.com/art...

I have to wonder how many users actually do this - I can't imagine that many. :\

Comment 9 (In reply to #3) by Raymond Camden posted on 11/25/2015 at 1:57 PM

Holy crap. So imagine this form field:

new-password, pword: <input type="password" name="p2_new" autocomplete="new-password">

In Firefox, it actually suggested one of my real passwords. I saw this by editing the DOM element and changing it to text. The value was a password I've used before. That has to be real bad, right?

Comment 10 (In reply to #4) by Craig Francis posted on 11/25/2015 at 2:07 PM

re:labels, it can do depending on the browser... if the browser does not understand these new autocomplete values they will use the <label> first before using the name to guess at what the field is for.

And you should ideally use them for all examples, so any inexperienced developers will hopefully start to learn that they are needed all the time.

Comment 11 (In reply to #8) by Craig Francis posted on 11/25/2015 at 2:08 PM

I think a fair few do on their iPhone/iPad, but I'm just hoping it becomes more useful given time (especially when password managers can start using this, rather than guessing).

Comment 12 (In reply to #9) by Craig Francis posted on 11/25/2015 at 2:10 PM

Ok, that's not good... I'll have to do some digging, but I don't believe Firefox actually reads the autocomplete value at the moment (it just defaults to "on", and I believe it always stays "on" even if you tell it otherwise).

That said, it really should not be pre-filling existing passwords (unless maybe that password was provided on the website/domain you were testing on?)

Comment 13 (In reply to #10) by Raymond Camden posted on 11/25/2015 at 2:12 PM

I absolutely agree I should use them in all examples - but specifically for now I want to keep the examples as is and then *add* examples with labels, to see if there is a change in behavior. Going to try that now.

Comment 14 (In reply to #10) by Raymond Camden posted on 11/25/2015 at 2:14 PM

Ok, in this test:

labels

<form>

<label for="fname1">First Name: </label>

<input type="text" name="fname1" id="fname1" autocomplete="given-name">

<label for="lname1">Last name:</label>

<input type="text" name="lname1" id="lname1" autocomplete="family-name">

<input type="submit">

</form>

I saw *no* change in terms of auto fill. No browser suggested a previous first/last name. Did I do it wrong perhaps?

Comment 15 (In reply to #12) by Raymond Camden posted on 11/25/2015 at 2:16 PM

The password it uses *was* one I used on my testing domain, but still it shouldn't suggest it for sure. I raised the comment on Twitter (I think I have a few Mozillians following me) to see if they can confirm this should be logged.

Comment 16 (In reply to #14) by Craig Francis posted on 11/25/2015 at 2:29 PM

Firefox: Does not really support autocomplete profiles, it simply remembers the values that have been entered into that text field for that website.
https://support.mozilla.org...

Chrome: Has fairly recently started using the autocomplete attribute, but it is still messy (and I can't work out what it uses to decide if it will use it or not, it seems to require at least one of the address fields to exist).

Safari: I've not done much testing, but it seems to work similar to Chrome.

Comment 17 (In reply to #14) by Craig Francis posted on 11/25/2015 at 2:30 PM

As for label testing, try this:

<form action="./">
<label for="AAA">First Name</label>
<input type="text" name="AAA" id="AAA">
<label for="BBB">Last name</label>
<input type="text" name="BBB" id="BBB">
<label for="CCC">XXX</label>
<input type="text" name="CCC" id="CCC">
<input type="submit">
</form>

Test that, then change XXX to "Address", and suddenly Chrome/Safari start working.

Comment 18 (In reply to #15) by Craig Francis posted on 11/25/2015 at 2:35 PM

I think it just comes under "we remember this websites password", and completely ignores the autocomplete attribute.

https://developer.mozilla.o...

"Many modern browsers do not support autocomplete="off" for login fields [...] This is the behavior in Firefox (since version 38), Google Chrome (since 34), and Internet Explorer (since version 11)."

Comment 19 (In reply to #18) by Raymond Camden posted on 11/25/2015 at 3:08 PM

Seems.... risky. I mean, I use a unique name/id. I used new-password, not password. Not sure why it would still suggest a known password just because type=password.

Comment 20 (In reply to #19) by Craig Francis posted on 11/25/2015 at 3:18 PM

For Firefox (at the moment), it doesn't matter what you set the autocomplete attribute to on the password field... it's always seen as "on", even if you explicitly set it to "off" then it just ignores it, and any other value is just assumed to mean "on" anyway.

And because of that, it just assumes any password field is the password field for the website, so it will auto suggest any previously used passwords for that website :-)

Comment 21 (In reply to #20) by Raymond Camden posted on 11/25/2015 at 3:28 PM

Fair enough - but I can't get Chrome to recreate the same behavior.

Comment 22 (In reply to #21) by Craig Francis posted on 11/25/2015 at 3:34 PM

I'm not sure Chrome is using the "new-password" value at the moment (nor do I think they have a way to generate a random password).

It doesn't help that there have been a few different versions of this spec, including things like "x-autocompletetype", and the ever changing list of fields for the address.

That said, I don't think its really changed for about a year, so hopefully the browsers and password managers will standardise on this one and we can all start using it... in the mean time, as website creators we can just add it and wait for everyone to catch up :-)

Comment 23 by mistersender posted on 12/1/2015 at 3:01 AM

I have had some fun struggles with autocomplete, and lacking time to blog, thought I would throw out a couple of gotchas I've found working with them (mostly js related):

- if you have events attached to `change` events on your form/fields, they won't fire reliably if the user uses native autocomplete. They *will* fire for `input` events, though, so at least that's an easy fix. Same deal on mobile devices. I think that is true for all input fields, selects still require some weird hoodwinkery with setTimeouts
- toggling autocomplete on and off with javascript does not work very well. I had an application that could be autocompleted from a googleplaces search OR native autocomplete. if googleplaces was used, i needed to disable native autocomplete... didn't work great. Don't know why yet.. it's really bothering me.

Comment 24 (In reply to #23) by Raymond Camden posted on 12/1/2015 at 9:02 PM

That's some pretty fascinating details - thanks for sharing that.

Comment 25 by Jason McNeill posted on 4/13/2016 at 12:01 AM

How's this for convoluted-yet-futureproof (I would apply masking to the characters in the password field with javascript):

<!-- Field names are always unique and therefore will never be remembered: -->
<cfset session.usernamefieldname = CreateUUID()>
<cfset session.passwordfieldname = CreateUUID()>

Username:
<input type="text" name="<cfoutput>#session.usernamefieldname#</cfoutput>">

Password:
<input type="text" name="<cfoutput>#session.passwordfieldname#</cfoutput>">