What if someone signs up for your web app and they type in their email address as [email protected]? They don’t notice, they never get their confirmation email, they never can log in again, the “forgot password” feature doesn’t work, and there is a lot of frustration and finger pointing.
Can’t we help with that?
I had a really basic idea to suggest common email domains with a <datalist>
suggestion dropdown. Essentially like this:

Datalists like that can be attached to any text-y input and they essentially provide suggestions. The user can still type in whatever valid value they want. It’s like a cross between a <select>
and and <input>
, I suppose.
Here’s how it works.
The Markup
Perfectly normal HTML that will work whether or not
<label for="email">Email</label>
<input id="email" name="email" type="email" placeholder="[email protected]">
Inserting the datalist with JavaScript
Datalist is an HTML element, but we can’t put it in the markup straight away because we don’t know what to put in it yet. The options we put in there will need to have the first part of the email address in them. That’s JavaScript territory, so we might as well only add the datalist when JavaScript runs.
jQuery, because I like it.
// Create empty datalist and append to DOM
var datalist = $("<datalist />", {
id: 'email-options'
}).insertAfter("#email");
// Correlate to input
$("#email").attr("list", "email-options");
The Email TLD’s
There are a handful of very popular “Top Level Domains” for email. Let’s put them in an array:
var domains = ["yahoo.com", "gmail.com", "google.com", "hotmail.com", "me.com", "aol.com", "mac.com", "live.com", "comcast.com", "googlemail.com", "msn.com", "hotmail.co.uk", "yahoo.co.uk", "facebook.com", "verizon.net", "att.net", "gmz.com", "mail.com"];
Adjust as needed.
Watching for Keystrokes
We don’t want to bug the user until they have pressed the “@” key and we know they are moving on to the domain part of their email address. So first, we watch for the key event:
$("#email").on("keyup", function() {
});
Then we test to see if the value contains the @:
$("#email").on("keyup", function() {
var value = $(this).val();
if (value.indexOf("@") != -1) {
// it's there, update datalist
}
});
We’d Better Get Organized
As this gets more complex, the more we should worry about spaghetti code and generally hard to maintain messiness. Let’s get organized using an object to keep it all together.
The structure becomes basically:
var EmailDomainSuggester = {
domains: ["yahoo.com", "gmail.com", "google.com", "hotmail.com", "me.com", "aol.com", "mac.com", "live.com", "comcast.com", "googlemail.com", "msn.com", "hotmail.co.uk", "yahoo.co.uk", "facebook.com", "verizon.net", "att.net", "gmz.com", "mail.com"],
bindTo: $('#email'),
init: function() {
this.addElements();
this.bindEvents();
},
addElements: function() {
// Create empty datalist
this.datalist = $("<datalist />", {
id: 'email-options'
}).insertAfter(this.bindTo);
// Corelate to input
this.bindTo.attr("list", "email-options");
},
bindEvents: function() {
this.bindTo.on("keyup", this.testValue);
},
testValue: function(event) {
var el = $(this),
value = el.val();
// remove the != -1 if you want the datalist to show up immediately as you type the @
// with it in place, it won't show up until you type the NEXT character
if (value.indexOf("@") != -1) {
value = value.split("@")[0];
EmailDomainSuggester.addDatalist(value);
}
},
addDatalist: function(value) {
}
}
EmailDomainSuggester.init();
Building the datalist on-the-fly
Notice in the above code I slipped in a little bit where I split
the value that we pulled out of the input at the @ symbol. That allows us to pull out the part of the email address before the domain. For instance, the “chriscoyier” part of “chriscoyier@gm”. Then we pass that over to a new function called addDatalist
. Now let’s use it:
// variables for iteration and string concatination
var i, newOptionsString = "";
// loop over all the domains in our array
for (i = 0; i < this.domains.length; i++) {
newOptionsString +=
"<option value='" +
value +
"@" +
this.domains[i] +
"'>";
}
// add all the <option>s to our datalist
this.datalist.html(newOptionsString);
Remove the datalist if we aren’t ready for it
As a final bit of cleanup, we should remove the datalist if the value in the input doesn’t have an @ symbol yet. Even if the user originally typed it but then backed up. We can handle that in our testValue function. We either update the datalist with the latest and greatest, or we remove it all together:
if (value.indexOf("@") != -1) {
value = value.split("@")[0];
EmailDomainSuggester.addDatalist(value);
} else {
// empty list
EmailDomainSuggester.datalist.empty();
}
Final Demo
Rather than paste a huge chunk of code here, you can check it out in the Pen:
See the Pen Help Complete Email Addresses with by Chris Coyier (@chriscoyier) on CodePen
A More Robust Solution
For the record, I’m not absolutely sure the datalist approach is a great idea. It would require some real UX testing to see if it’s actually helpful. It may be hurtful in the form of user confusion. I am more sure that some form of email domain checking is a good idea.
There is an open source project on GitHub called mailcheck.js that looks pretty good.

jquery.email-autocomplete.js is another option.
Yup
Have you used something like this? What do you think about the approaches? Have you done any UX testing around this or similar ideas? Do you have any other ideas to approach the “wrong email” problem?
Sweet usability trick. Steve Krug would be proud.
I’m not sure which I like better, but I have seen the use of the datalist before…can’t remember which site but (from an advanced user perspective) I like the list. From a developer standpoint, the “Did you mean…” seems easier and much cleaner.
Wooow Ryan thanks for ruining my day at the office, a simple nsfw alert should be added.
I like it. I think that a solution to the mistyped emails would definitely be very helpful but I agree with your last comment that the ‘Did you mean [email protected]?’ solution may be better. It’s a bit less obtrusive, and less shocking to the user.
If a layperson was signing up for a brand new site and it provided them with a list of emails and they recognize some of them as addresses they have used, it may bring up privacy concerns (even if there isn’t an actual privacy issue with this solution.)
FWIW, according to limited research I did 2 years ago, mistyped emails occur on around 1% of form submissions
So, to put it another way. If you have 1,000 signups to your site per month, 10 of them will fail, perhaps 5 of them will contact you in frustration… or about 30-60 minutes per month of support, depending on how difficult it is in your CMS to change the email address.
If you have 10,000 signups, it’s 2 days of work.
Either way, it seems like the few hours it takes to research and implement this would pay off in a matter of weeks or months. If you already have a user base, taking a look at the most common domains would make this technique a whole lot more usable. In fact, you could go one step further and automate monthly maintenance, checking domains used recently to populate the list.
I think it will cause some confusion since a dropdown like that is reserved for the browsers native functionality of displaying recent form history. And you’d have to disable that which is not only confusing but annoying also.
I agree. The mailcheck.js UI seems to be less confusing.
Autosuggest is used in various forms, particularly by google. I don’t think you’d find much confusion. However, if you’re really worried, you could visual distinguish it as a suggestion and the word “suggestions” somewhere in the list.
Nice post as usual. The Treehouse show recently covered a cool jQuery form validation library: Formance.js by Omar Shammas. check it out!
(http://teamtreehouse.com/library/the-treehouse-show/episode-59-form-validation-safari-push-notifications-javascript-performance)
http://omarshammas.github.io/formancejs
I’m also curious how these solutions might compare to the ubiquitous pattern of requiring users to enter their email address twice (as a way of trying to reduce mistyped emails). I personally prefer these.
I have used mailcheck.js a few times and the users really dig it.
I also added an event listener (Google Analytics) to the “Did you mean” link, it helps when you want to know if it makes any difference.
Seems like a pretty good technique, however not sure if I’m the only that noticed this or not, but in Safari on Mavricks the menu does display after typing ‘@’ think it has something to do with the new autofill passwords/usernames.
I guess it’s like a built in solution to the problem, only allowing you enter a valid e-mail address you have entered on your mac. It will definitely be nice on older systems that don’t support such a feature.
Meant to say it does Not show up.
Same here, running safari 6 on ML, code pen not working.
I don’t see how this is intrusive when it’s basically the exact same behavior that all browser already have: A dropdown appears on form fields that are similar to ones you have filled out before, or if you’re filling out the same form (like the Commens form here*).
Also, this is exactly what we know as “Live Search” introduced by Google several years ago (I’m not talking about “Instant Search”, that’s something else).
And I don’t see anyone on the web complaining that the above two features are intrusive, and this idea from Chris’ piggy-backs on the same concepts.
I do see one technical issue and one potential usability issue though:
The technical issue is that this script did not work for me in my iPhone 5 with iOS 6 (and I plan to wait even longer before I give in to flat). Can anyone confirm in iOS 7?
The potential usability issue I see is that users may feel apprehensive seeing this feature “mysteriously know” their e-mail address before they’ve even completed it. Just saying. Which in this case, maybe mailcheck.js could have an advantage since it happens after the user has finished. Again, just saying.
I was also wondering: Every time I’m going to post on CSS-Tricks.com I need to fill out the fields at the top and since I’ve filled them before then Firefox is showing me the dropdown with the emails I’ve used in the past, so: What happens when these two features are combined, the browser’s dropdown and the script’s dropdown?
*See drop here.
Spoiler: It actually combines very well since you can see the top section is the browser’s own dropdown, and the one below is the script’s, clearly separated by the thin line.
I think I’d rather just have two fields for the email address, just like with passwords.
Makes sense to me :)
I dunno about you, but speaking as a user, I always just copy/paste the second email (Which totally defeats the purpose.) And in the few situations where that ability was disabled, it absolutely infuriated me.
Interesting idea, although I wonder if it might increase the risk of people using other email providers than the big ones accidentally autocompleting to, for instance, a gmail address.
Some nitpicking with the code:
It seems you are rebuilding the datalist on every keystroke after @ which seems a tad wasteful. Might be cleaner to remember the old “value” (the part before @) and only rebuild when it has changed.
Is it just me who thinks the more “ways” we have to do something, the harder it seems to actually decide on which one to use?
I can see (mainly) pros and (some) cons for all three methods; dual email fields, datalist and “did you mean?” so, apart from trying to second-guess what your “average” user may or may not find “confusing” I guess it boils down to just picking one and going with it.
Unfortunately, I like ’em all O.O
If you are a tuts subscriber, check out this tutorial I wrote over a year ago about doing something similar
https://tutsplus.com/tutorial/building-a-mobile-friendly-form-with-email-domain-suggestion/
NEAT, as usual, Chris! I might also prefer the »mailcheck.js« style after i tested it out. Google Chrome gives me an autocomplete for an
<input type="email">
right away. Then the autocomplete get’s suddenly replaced with the huge list, kind of confusing. So maybe the browser autotfill has already solved this enough? But again: great small idea!A server-side (or client-side with Ajax) solution would be to use this PHP function : checkdnsrr().
Basically, you can verify if the mail server entered in your email address is a real mail server.
See the doc : http://php.net/manual/fr/function.checkdnsrr.php
This seems like the easiest and most future-proof (Not that gmail.com is going anywhere, but some providers might) solution.
Oftentimes designers forget that there’s a server behind their creations – May as well use it.
Just encountered this when I was setting up my business email! and man was it ever helpful! I mis-typed the domain by accident and it corrected it ! I love this site!
May improve experience by ignoring the Down and Up arrow key presses. ;-)
no, that would be fatal to the ux…
How come you get such rubbish ideas?
I think there is a typo in your domain list. At least I know of gmx.com as a email provider, whereas gmz.com doesn’t seem to be one. A typo in a tool that aims to reduce typos is somewhat ironic :-)
We take the “did you mean x?” route at Vimeo. MailCheck looks like a great library, but like the docs state, you should absolutely consider supplying your own domain suggestions based on what your site visitors most often use. The downside of this is that you can find yourself doing a lot of updates.
Yahoo and Hotmail’s love of multiple TLDs have been the biggest issues so far, so I just recently created a separate loop to populate my list with all possible permutations.
Hi Chris nice and cool idea, But cannot select any option using the keyboard.
I am not able to select any options from the dropdown using the arrow keys
I heard that’s a problem in Firefox. Works in Chrome for me. It’s just a native Datalist, in which keyboard commands do work in Firefox, so it’s a code issue. Feel free to fork and fix =)
@rocketmail.com is not in the list ><