Building a Mobile-Friendly Form with Email Domain Suggestion

This tutorial will teach you how to create a responsive web form which goes above and beyond setting <input type="email"> to help users enter email address information. This form will assist users (primarily mobile) by automatically suggesting popular email domains.

Introduction

Designing for mobile is becoming big in web design. With an ever increasing number of users accessing content from mobile devices, design methods such as responsive web design are becoming standard practices in improving usability.

The aim of this tutorial is to do precisely this — incorporate responsive web design techniques to improve a usability concern from a mobile perspective.

So, let's dive right in by first understanding the usability concern we are addressing.

The Problem

Let's face it, filling out forms on a mobile device can be frustrating. As a general rule of thumb, you could probably state that as the number of fields in your form increase, the likelihood that the user will actually complete the form decreases. Why? Because entering lots of information from a mobile device is simply more difficult than with a traditional desktop or laptop due to factors such as smaller and/or virtual keyboards.

Solving With Software

Mobile device makers recognize this problem with device input and have created software solutions to better assist users. For example, think of Apple's iPhone. Because the iPhone's keyboard is virtual, the characters it displays can change at any given time depending on context. So, developers can label an <input> element's type attribute and the keyboard will display characters relevant to the form field's requested data type.

As you can see, if you're entering just normal text, you get the standard keyboard. If you're entering an email address, the "@" symbol and the "." (period) become prominent. Or, if you need to enter a number, the keyboard will change to give you numbers first!

Understanding the Anatomy of an Email Address

Consider the anatomy of an email address — what does every email address have in common? Each email has three key parts:

A username

The "at" symbol (@)

A domain

Every domain has a period (.)

So, when users encounter a form field that asks for an email, we know that they will be required to use the @ symbol and a period, because those are common to every email address. That's why setting <input type="email"> assists users! It gives them easy access to the essential components of any email address.

Why Stop There?

It's possible we could provide a little more assistance to users entering their email address. A large percentage of users are using email domains that are very common. A quick Google search will show some of the most popular email domains are:

@aol.com

@hotmail.com

@gmail.com

@yahoo.com

and so forth

If a large portion of your user base is using the same email domain, why make them fill it out? What if we provided a kind of "auto suggestion" to the user as they filled out the email portion of the form? That way, as they began to type the "y" in "yahoo.com", they would get a suggestion saying "hey, are you trying to enter "yahoo.com"? If so, just tap here and we will fill in the rest for you!" This is all possible from a design perspective and that is what we are going to do in this tutorial.

Step 1: Getting Started With HTML

Step 2: Adding the Dependencies

Now, let's add the links to the markup's dependencies. First we will include a link to Google's hosted version of jQuery as well as a link to "script.js" which will hold our javascript code we create later on. Let's put these right before the closing </body> tag.

Let's also include a link to our CSS file (which we haven't created yet). You can put it in the <head> element.

<link href="styles.css" rel="stylesheet" />

Step 3: Designing Flexibly

Because this page will be responsive and flexible down to mobile, we must make sure to set the viewport so mobile devices render our page properly. If you want a more in-depth analysis of what this code is doing precisely, check out Ian Yates' article on the viewport meta tag. Otherwise, simply add this snippet of code in your <head> element.

Step 4: Creating the Container

Let's start by adding a main container and a description of what our page's purpose is:

<div id="container">
<h1>Email Domain Auto-Suggest</h1>
<p>This form automatically suggests the popular email domain addresses. Although compatible on desktop computers, this feature is designed primarily for mobile devices. It will assist users who use popular email services such as gmail and hotmail.</p>
</div>

Our basic markup looks like this:

Step 5: Creating the Form

Now let's insert the markup for our form. We will use an unordered list to help give structure and semantic meaning to our form.

Note: Don't worry too much that we haven't given our <label> and <input> elements all the normal attributes. Since this tutorial will not be covering form handling and submission, we won't worry about that too much.

Another Note: Our markup for the actual domain suggestion will be injected using javascript, that's why we don't have it here.

We used CSS to add some basic styling. We also used a fixed width of 500px with some padding for our content and the margin: 0 auto centers our div in the middle of the page. The problem with setting the div's width at a fixed value (in pixels) is that when we get below our fixed width (500px) some of our content gets cut off:

The Better Way (Liquid Width)

To make our container flexible, we'll take out our fixed widths and use percentages instead. Here's the values we will add/change:

#container {
width:80%;
padding:0 5%;
max-width:500px;
}

Here we set our container's width to be 80% of the browser's viewport with 5% padding on each side. You might be saying "but that only adds up to 90%!" and you're right! The other 10% is actually being used as a margin (5% on each side). We don't have to specifically set it because it's being determined by margin: 0 auto

Also, we added max-width:500px because we don't want our form ever being any bigger than that. So if someone has a 2100px browser window, our container div won't be 80% of that. Rather, it will just stop expanding at 500px! Cool no?

Now you can see how our content properly resizes according to screen size.

Step 8: Typographic Styling (CSS)

You probably noticed the <h1> type running over itself when the browser size gets small and the text goes to the next line. We'll fix that by adding a few typographic styles to our headers:

You'll notice we set the <input /> fields with 100% width. With our additional padding, that will actually make the inputs extend beyond their parent container! To solve this, we use the box-sizing:border-box rule. This tells the browser to calculate the element's width at 100%, irrespective of any padding or borders it might have; thus making it always fit inside its parent container. To learn more about this property, see Ian Yates' article Encourage Responsive Form Elements to Play Nice

Now we've got a pretty decent looking form as far as structure and spacing!

Step 10: Submit Button Styling (CSS)

Now let's apply some styling to our submit button. We'll make it rather visually prominent as many submit or call to actions buttons are:

We set the width at 80% which will work great at smaller sizes. But when it's in a desktop browser we don't want the button spanning the entire form. So, we used our handy max-width rule to tell the browser not to render the button wider than 300px.

Center

We set the display to block and gave it auto margins. This centers the button in the parent div.

Visual Styling

We added some visual styles using borders, box-shadows, etc. We also used the CSS3 background gradient feature. You can find excellent generators for this kind of code online.

Step 11: Creating the Suggestion Markup

At this point we've got a pretty nice looking form that works all the way down to mobile without even using media queries! Now we'll create the markup for the email domain suggestion and style it.

Remember, this markup is something we will insert with our javascript. So once we put it in our document and get it styled how we like it, we'll actually take it back out. Doing it this way is just easier for development purposes.

So let's insert a <span> element right after our <input /> element:

<span class="suggestion">test@gmail.com</span>

Step 12: Styling the Suggestion Field (CSS)

As you can see, our suggestion just looks like text right now. So, let's add some CSS styles so it will look more like a suggestion field:

Giving our suggestion field a line-height rule rather than a height rule will center the text vertically in the box.

Positioning

As you can see, we used absolute positioning for our suggestion field. We offset it from the left a little and from the top so it doesn't cover the input field.

Visual Styling

We added some visual styles using borders, box-shadows, etc. We also used the CSS3 background gradient feature (as we did earlier on the button element).

Step 13: Suggestion Field Popover Styles (CSS)

Now we have the suggestion field all styled, but we want to make it appear like a suggestion over the input field. We'll use a little triangle to accomplish this. To make the field appear clickable, we'll also make sure the hover state shows the field as being clickable:

The triangle could be added using images, but we did it using pure CSS. Because we're using a pseudo selector, we have to use the triangle's corresponding escaped unicode since we're using the content:"" rule. Then we just use positioning to get it where we want it.

Now we have something like this:

Step 14: Adding the Suggestion Field Hover/Active States (CSS)

Now we want to add a little interactivity to our suggestion field. We'll make a hover and active state by simply coloring the background. This will make sure we tell the user they can and have interacted with the field.

Congrats! Now we are all finished with the HTML/CSS markup. Now we just need to add the javascript interactivity!

Note: Don't forget to remove the <span> element now. We'll insert it using jQuery later on.

Step 15: Understanding the Interactive Aspect

Before we actually dive into writing our domain suggestion script, let's make sure we outline and understand what we are trying to accomplish.

Creating the Email Domain Stack

What we want our script to do is detect if the user is trying to enter an email domain that matches some of the more popular email services on the web. A quick Google search will reveal that the following are some of the most used email service domains on the web:

@aol.com

@comcast.net

@gmail.com

@hotmail.com

@me.com

@msn.com

@yahoo.com

Obviously you could add/subtract as many email domains to this list if you want, but this is a good start for what we're trying to accomplish.

Suggesting a Domain

So what if the user is trying to enter one of these domain addresses? Then we will use our script to suggest it! This will allow the user to simply click/tap on the suggestion and have the desired email domain appended to what they have already entered. If it is not what they want, they can simply ignore the suggestion.

Step 16: Setting up jQuery

Let's create our "script.js" file and start off with the following code to implement jQuery:

$(document).ready(function() {
//script code will go here
});

Step 17: Adding the Suggestion Box to the DOM

If you remember, we inserted a <span> element with a class of "suggestion" after each input element and styled it just how we wanted our suggestion boxes to appear. Once we styled it correctly, we removed the markup from our HTML

Well, now we are going to insert that markup using jQuery. We will use the insertAfter() method:

This line of code will find every input element on the page that has an attribute of "type=email" (which is used on each of our input elements). It then inserts the markup we specified (<span class="suggestion"></span>) after each element (hence the name). Then we hide all occurrences of the suggestion box (because we have nothing to suggest yet!)

Adding it with javascript works well because it's markup that only needs to be there IF the user has javascript enabled on their computer.

Step 18: Catching the User's Input Value

In order to determine which email domain to suggest, we need to know what value the user is entering. So we need to watch the input field that's in focus and every time the user presses a key on the keyboard we'll catch the new input value and store it in a variable.

We can find out what the user is entering by using the keyup() event. By attaching keyup to each input element, we can trigger our script to get the value on the input field each time a new character is entered.

So now every time the user adds another character to the input field, jQuery will grab the value and store it in the "value" variable.

Step 19: Checking for the @ Symbol

Now the user's input is being stored in the "value" variable. However, we don't really care what their email username is. If our value variable equals "joe" that doesn't help us because we don't know what domain the user is trying to enter. But, if our value variable equals "joe@a" then we can guess that maybe the user is trying to enter "joe@aol.com" and we can suggest "@aol.com".

So, what we want to do is check the value variable on each keyup() event and see if it contains a "@" symbol. If it does have an "@" symbol, we know the user is ready to enter in their email domain address.

So we are going to store the position of the "@" symbol in a variable for use later. We will do this using the indexOf() method. We simply create a new variable (a_pos) and set it equal to the index value of the "@" in the value variable.

var a_pos = value.indexOf('@'); // value will default to -1 if not entered

Note that if the "@" symbol hasn't been entered yet, our variable a_pos will default to a value of -1. Otherwise, we get the character's position in the string.

Step 20: Storing the Parent Element for Context

We also want to store the parent element of whatever input element is in focus by the user. This will be useful when we show our suggestion markup because we won't want to show all of the suggestion boxes on the page. Rather, we will only show the one that is in focus (more on this later).

var parent = $(this).parent();

Step 21: Suggesting an Email Domain

Now we have everything in place to see if the user is actually entering an email address! So what we'll do now is setup an if/else statement.

If the "a_pos" variable has a value of -1 we know that the user hasn't entered the "@" symbol yet. If it has any other value, we know that the "@" symbol has been entered. So let's setup the following if/else:

Predicting a Domain

If the '@' symbol has in fact been entered, we want to check and see what the character AFTER the @ symbol is. If it's a "g" we could suggest "gmail.com" to the user. If it's a "y" we could suggest "yahoo.com" and so forth.

This code is saying "if the first character value AFTER the position of the '@' symbol is equal to 'a', then suggest 'aol.com' to the user."

Note: You'll notice we are selecting the .suggestion class. Because we have multiple 'suggestion' classes, this will select every 'suggestion' class on the page, which we don't want. This is why we set the 'parent' variable and use it as our selector's context: $('.suggestion', parent). jQuery will now only select items with a class of 'suggestion' in the context of the focused input field's parent!

Step 22: Completing all Email Domain Suggestions

Now that we have the code to suggest email domains, we just need to test for other values, such as 'g' for 'gmail.com' and 'y' for 'yahoo.com'. Since we're using an if statement, let's append all the other domain address suggestions using an else if statement.

Suggesting Domains Whose First Letters Match

Now we want to suggest 'msn.com' and also 'me.com'. Both start with 'm' so we will do a nested if/else statement. We're going to assume 'msn.com' is the more widely used domain address, so we will suggest it first:

This piece of code is saying "if the character AFTER the '@' symbol is 'm' then run the code inside". The code inside is saying 'if the SECOND character AFTER the '@' symbol is 'e' then suggest 'me.com'. Otherwise, suggest 'msn.com'.

What if There Are No Matches?

What if the user enters something like "john@z"? We don't have any email domain suggestions that start with the letter 'z'. So, at the end of our if/else if statements, we will put an else statement that hides the suggestion box. This basically says "if there are no suggestions matching what the user has entered, hide the suggestion box."

Step 23: Closing the a_pos if/else Statement

We have put in all the email domain suggestions IF there is an '@' symbol that has been entered. If the '@' symbol has not been entered, we will simply hide the suggestion box.(This means if the user types "john@y", the "yahoo.com" suggestion box will pop up. But, if the user hits the delete key the suggestion box will disappear).

else {
$('.suggestion', parent).hide();
}

Our Entire Keyup Code

So, our entire block of code for when a user makes a keystroke looks like this:

If you test this in the browser, you'll see suggestions appear according to the email domain address you attempt to enter. Clicking on them won't actually do anything though — that's our next step!

Step 24: Appending the Suggested Email Domain

So what happens if the user clicks on one of our email domain suggestions? We need to append the suggested domain to whatever they have entered so far.

So, for example, let's say the user has entered "john@a". That will trigger the "aol.com" domain suggestion to appear. If the user clicks that suggestion, we want to save them the effort of typing the rest of the address and append it to whatever they've entered so far. So the input field's value will go from "john@a" to "john@aol.com"!

To accomplish this, we will need to watch for when a user clicks on a suggestion box. So let's have jQuery watch for that:

Step 25: Declaring the Variables We'll Need

In order to properly append the suggested email domain the user selects, we'll need some variables.

Parent Context

First we'll need to select the parent of whatever suggestion box was clicked on. Once again, this will be used for making selections in context of the input field that is in focus.

var parent = $(this).parent();

The Email Domain Suggestion

We need to know what the actual suggestion is that we are making to the user. So for example, if we are suggesting "aol.com", let's store that value in a variable. Since we are inside the currently clicked suggestion box, we'll use jQuery's $(this) and text() method to get the value of whatever is being suggested.

var suggested_val = $(this).text();

The User's Current Input Value

We need to know what the user has entered so far. So, if they have entered "john@a", we'll store that value in a variable. This is where we use the parent variable we set earlier for selection context (since we don't want to select all occurrences of the 'suggestion' class, we only want the one that was clicked on).

var input_val = $('input[type=email]', parent).val();

Position of the '@' Symbol

Once again we need to know the position of the '@' symbol in the string the user has entered. So we'll use the indexOf method we used earlier. This will check the input_val variable (what the user has entered so far) and look for the position of the '@' symbol.

var a_pos = input_val.indexOf('@');

Email Username

If the user clicks on "aol.com" we know that their email domain is "@aol.com". So we have to get everything they've entered BEFORE the '@' symbol. That is their email username. Once we have that value, we can append the suggested email domain to it.

To do this we'll create a variable called before_a and set it equal to the result of the substr method.

The substr method is used on the input_val variable (the user's currently entered value in the input field). It will extract the characters from a string, beginning and ending at the parameters we specify.

var before_a = input_val.substr(0, a_pos);

Step 26: Appending the Suggestion

Now that we have all our variables in place, we can append the suggested email domain the user clicked on. We'll do this by selecting the input box they are focused on (we can do this in the context of it's parent, as explained before) and then setting the input's value using the variables we setup:

$('input[type=email]', parent).val(before_a+'@'+suggested_val);

This sets the input's value to whatever the user had entered up until the '@' symbol, the '@' symbol itself, and then the suggested email domain they clicked on.

Don't forget to hide the suggestion box once the user clicks on it:

$(this).hide();

For a more visual representation of what we've done here, check out this image:

Step 27: Hiding the Suggestion Box

What if the user is typing in an email address and doesn't use the email domain suggestion we provide? When they click outside the input field (blur event) we need to hide the suggestion, as it's no longer relevant. So we'll do that using the following code:

$('input[type=email]').blur(function() {
$('.suggestion').hide();
});

However, there's a problem with this. If the user clicks on the suggestion, not only will that fire the $('.suggestion').click function, but it will also fire the $('input[type=email]').blur function (since the suggestion box is outside the input element). This will result in our suggested email domain not actually being appended. So we'll have to fix this.

Step 28: Hiding the Suggestion Box: A Fix

We can solve this problem by tracking mouse events on the suggestion box using a boolean variable.

We'll create a variable called "mouseOver". It's pretty self-explanatory. If the user hovers over the suggestion box, we'll set its value to "true". If they mouseout (or don't hover over the suggestion box) the "mouseOver" variable will be reset to false (it's default value).

What We've Done

The idea here is discovering the user's intent. If they are hovering over the suggestion box, we know they plan on clicking on it. But, if they aren't hovering over it, and then click outside the input field (blur) we can execute the code to hide the suggestion box, because we know the user wasn't planning on clicking on it!

So now our code for hiding the suggestion box should look like this:

// we need to track mouse events on the suggestion field. If the user is hovering over the suggestion,
// it will execute the insert_suggestion
// otherwise, on mouseout it will hide the suggestion
var mouseOver = false; //default state is false
$('.suggestion').mouseover(function() {
mouseOver = true;
})
.mouseout(function() {
mouseOver = false;
});
//hide suggestion when field is out of focus
$('input[type=email]').blur(function() {
if ( !(mouseOver) ){
$('.suggestion').hide();
}
});

Congratulations! You've created a responsive web form that assists users with popular email domain addresses. There are some enhancements that could be made to this script. For example, what if the user enters "john"@microsoft.com"? The "@msn.com" suggestion will actually appear until they are not focused on the input field anymore. You could add a line of code that hides the suggestion if the user doesn't click on it within a certain amount of characters. For example, if they type, "john @micro", we can assume they don't want to use the suggestion we've provided. At that point, we could hide our suggestion.

Play around with the script and HTML and see what additions you could make to improve the user experience of filling out forms!

Jim Nielsen currently lives in NYC working as the lead designer for an enterprise software startup. As much as he loves the city, he misses the red rocks of his boyhood home and the beauty of the desert southwest.
He loves to ski, golf, fish, read, eat street tacos, learn new things (currently he's into calligraphy), and take road trips immersed in the music of Bob Dylan. However, his true passion is to analyze complexity and transform it into simplicity.