Forms—The Complete Guide—Part 2: Input Types

Sat 05 April 2014
By Martin Polley

Forms are one of the most important parts of any site or app—they are the most common way for our users to give us the information that we need to help them do what they want to do.

But in many instances, we design forms statically, often as wireframes. But so often, what makes or breaks a form is what it's like to interact with it. When the user clicks on a particular radio button, some additional inputs appear. How does that happen? More importantly, does the user understand what just happened?

Things like this are next to impossible to explore using static deliverables. But with a prototype of a form, it's easy. And with a prototype form made in HTML, you can make it look and behave exactly like the real thing. Which means that once you've validated it with users, you can be sure that it can be implemented so that the appearance and feel are just the same.

This series does not try to explain what your form should contain, how the fields should be grouped and laid out, where to put primary and secondary buttons, and so on. There are lots of great resources out there that do that already. (Like Luke's and Caroline and Gerry's books. Or Justin's article.)

No. What this series does is give you the how. You've already figured out what you think your form should contain and how it should behave. These posts will give you everything you need to know to make a prototype of your form in HTML, something that looks, works, and feels like the real thing. Which you can then use for usability testing, for getting stakeholder buy-in, and as a living specification for developers.

In the first post in this series, I showed you how to lay out a form and align the labels the way you want, using HTML and Foundation.

In this post, I'll show you the different types of inputs available to you and how to use them.

To make the most of this post, I strongly encourage you to get your hands dirty by actually typing in the examples and then opening them in your browser to see how they look and work. From personal experience, this gets it into your brain, into your fingers, much better than just copying and pasting.

Input types

There are several different HTML elements that are used in forms. Buttons get their own element (<button>), as do drop-down lists (<select> and <option>), and multi-line text inputs (<textarea>).

But most form elements are the <input> element, with a type attribute that specifies what kind of input it is.

Let's look at them one by one.

If you're following along and actually typing this stuff in, you need to set up a new Foundation project, open up its index.html file, and delete all the sample content (see this post to find out how).

Then add an empty <form> element and the necessary Foundation layout elements.

Once you've got that set up, you can just add each example within the <fieldset> tags, after the <legend> element.

Note: In the code samples below, you'll notice that all the <input> elements have both a name and an id. Why is this? It's because you need the id to be able to identify individual HTML elements (to style them with CSS, etc.). But for a real form, you need name so that the data that gets sent to the server will be labeled correctly. These aren't proper forms, they're just prototypes. But it's good to do it properly from the start. So the rule of thumb is: for <input>s, use both id and name, and give them both the same value. (An exception is radio buttons—I explain why they're different below.)

Text and its variants


Input of type text

An <input> of type text is just a simple input field. There are no restrictions on what the user can type in it (though there are attributes that you can add to do things like limit the length of the field's contents—see below).


Input of type password

An <input> of type password behaves exactly the same as a text input, except that whatever you type in it is obscured.


Input of type email

An <input> of type email is the same as a text input, except that on phones and tablets, the keyboard that is displayed has @ and dot keys as standard—you don't have to go digging for them:

It also gives you validation for free. If you enter something other than a valid email address and then submit the form, the browser will do something like this:

Input of type email, invalid

(This is true for desktop browsers anyway. Most mobile browsers don't do this yet.)


Input of type url

The url <input> type is similar to email, except here you get a keyboard layout with slash and dot keys (and maybe others, such as .com).

Again, desktop browsers validate these automatically:

Input of type url, invalid

Phone number

Input of type tel

The tel <input> type, as we saw in the previous post, gives you a phone keypad on smartphones:


Input of type number

The number <input> type doesn't restrict what you can type, but on smartphones (the iPhone, at least), you get the regular keyboard, switched to numbers-and-symbols mode:

Different desktop browsers render this input differently. In IE and Firefox, it looks the same as a text input, but in Chrome and Safari, it gets spinner controls for increasing and decreasing the value:

Input of type number on Chrome/Safari

You can set minimum and/or maximum values, and a step size. These affect the behavior of those spinner controls.



Input plus datalist, empty


Input plus datalist, typing

You can use an <input> with a list attribute paired with a <datalist> element to get something that is kind of a cross between a text input and a drop-down list. As you type in the input, a dropdown list shows you matching options. You can click on an option or use the arrow keys and Enter to select.

Other types

There are a number of other <input> types that were introduced with HTML5, but most of them are not widely supported yet. These include color and various date and time inputs, such as date, time, datetime, datetime-local, week, and month.

For now, you're better off using things like the jQuery Datepicker.

The rest


Input of type checkbox

If you give an <input> a type of checkbox, you get a checkbox. These usually have their label to the right. For checkboxes, the for attribute is particularly important—it makes the label clickable—clicking it is just like clicking the checkbox itself. Adding the checked attribute (which doesn't take an argument) makes the checkbox checked when the page loads. For a prototype it doesn't really matter, but a checkbox in a real form must have a value attribute.

Radio buttons

Input of type radio

Like checkboxes, with <input>s of type radio, the label usually comes after the input. And for and checked work the same here too. Here though, be sure to give all the radio buttons in a group the same name attribute—this tells the browser that they belong together, and that only one can be selected at a time. Again, like with checkboxes, every radio button must have a value.


Input of type range

An <input> of type range gives you a slider. Like with number, you can specify a minimum, maximum, and step values. But this control is not hugely useful on its own—if precision is not an issue, you can probably get away with just adding text before and after the <input> to show the maximum and minimum values. But in most cases, you'll probably want to provide some sort of feedback so the user knows what value they have selected.

This is not difficult. It requires a tiny bit of Javascript, but you'll see in a minute that it's really no big deal. We just need to take the existing bit of HTML and add an <output> element to show the value. And we add an oninput attribute to the <input> to tell it what to do when its value changes.

In this version, the <input> and <output> elements are in separate columns, and I've given the <input> a width of 100% so it will stretch to fill its column:

Input of type range, improved

The little bit of Javascript that is the value of oninput just sets the value of the output (range_value.value) to the value of the input (range_input.value). (range_value is the <output>'s ID, and range_input is the <input>'s ID. Adding the dot and value just means “the value of the value attribute of the element with this ID.”)

Drop-down lists

Closed: Input of type select, closed

Open: Input of type select, open

Drop-down lists are not <input> elements—they are made up of a <select> element containing a number of <option> elements.

This is fairly straightforward. One thing I've added here though is the first <option>—it prompts the user what to do, but is not actually an option they can select. (The selected attribute means it is what is displayed in the closed dropdown before the user interacts with it.)

Without this option, "Option 1" would be selected by default. Usually we don't want anything to be selected by default.



A <textarea> is like a text <input>, except it lets you enter multiple lines of text. Like all the text-like <input>s, its width is 100% of the column that it's in.

As for height, there are two ways to set this. One way is to set the height in CSS (or directly on the element by adding a style attribute). The other way is to use the rows attribute, like I'm doing here. This makes the <textarea> tall enough to fit six lines of text.

(The style="height: auto;" attribute is to get around a bug in Foundation. If you set the height to a specific value instead of using rows, you won't need this.)



Most forms have buttons that you have to click to send the information you've entered to the server. Some also have a button for a secondary action, to cancel out or to reset the form (though some argue that such secondary actions are usually a bad idea).

Here, the buttons are <input>s of type submit and button. (submit is a special kind of button for submitting a form.) The right place to put these is after the closing </fieldset> tag.

The Submit button gets a class of button to make it into a nice-looking Foundation button, while the Cancel button also gets a class of secondary to make it visually less prominent.

Foundation also lets you use the <a> element for making buttons—just give it a class of button. It also lets you do stuff like make buttons smaller, give them rounded corners, and so on, just by adding classes.

Other clever Foundation stuff

Foundation lets you do some clever things that the standard HTML elements don't let you do.

For example, you can combine an input with a label to get something like this:

URL input with prefix

You can see the code for that here.

You can also combine an input with a button to get this:

Text input with postfix button

The code for that one is here.

Important attributes

I mentioned a few attributes along the way, like id and name, checked for checkboxes and radio buttons, min, max, and step for number and range type inputs, and so on. But there are some others that you need to know about:


Browsers try to help us by automatically filling in form fields for us when they can. But sometimes this is not appropriate, for example, for sensitive information such as bank account and credit card numbers (and even passwords in certain cases, though beware of being annoying with this one).

Setting autocomplete to off for an input tells the browser not to fill it in automatically.


On each page, you can give one (and only one) form control the autofocus attribute. This field will get focus when the page loads, so the user can start interacting with it without having to click in it or tab to it.


A disabled input

A control with the disabled attribute gets greyed out and you can't interact with it. This may be because it's not relevant unless some other control has a particular value. (For example, if your form has a "How did you hear about us" section with radio buttons, the last one might be "Other", with a text input so the user can type something that's not in your list. It makes sense to make this input disabled unless "Other" is selected. I'll cover this sort of thing in more depth in a subsequent post.)


Text-type inputs (text, email, url, tel, etc.) can have a maxlength attribute. This lets you specify the maximum length in characters. Most browsers won't let you type any more once you hit the limit. This is handy for things like phone numbers, which can't be longer than a certain number of digits.


The <select> element and <input>s of type email (also of type file, for uploading files, which I haven't covered here) can take the multiple attribute. This lets you select multiple items in a dropdown or specify multiple email addresses, respectively.

A drop-down list with multiple selection

Notice how the <select> is displayed differently when multiple selection is enabled.


pattern tells the browser what an acceptable value looks like. I'll cover this in a subsequent post when I talk about validation.


The placeholder attribute

The placeholder attribute puts hint text inside the <input> (or <textarea>), to give the user an idea of what they need to type. It disappears when you click in the <input>. Some sites use it to indicate which fields are mandatory and which are optional.

IMPORTANT: Do NOT use this instead of a <label>. It is very bad from both accessibility and usability points of view.


The required attribute means that a field is mandatory. It doesn't change its appearance (an asterisk doesn't magically appear next to its label), but if you submit the form without filling it in, you'll get a helpful message:

The required attribute


The tabindex attribute (which has a numerical value) determines the order in which controls get focus when the user presses the Tab key.

If you're doing something weird with your form layout such that the inputs are in a different order on the screen than in the page source, you should use the tabindex attribute to make sure that focus jumps to the right input when the user tabs between them.

Special considerations

On phones and tablets, there are additional challenges that we face. How often have you come to sign in or register at a site on your phone and seen something like this?

Inappropriate use of autocorrect and autocapitalize

On, as I'm typing in the User ID field in the login form, my phone is automatically capitalizing the first letter and wants to correct what I'm typing to words it has in its dictionary. So now I have to tap the little "x" to dismiss autocorrect, and go back and change the capital "M" to a lowercase one. Grrr.

For fields like this, there are two attributes that we can add to turn off this antisocial behavior: autocorrect and autocapitalize.

They both take the same values: on and off. By default, they are on.


Hopefully you now have a pretty good idea of the building blocks that you can use to create your prototype forms.

In the next post, I'll show you how to group inputs into logical (and less overwhelming-looking) groups and how to provide help to users while they are filling in the form.

This was originally published on Boxes & Arrows on 25 March 2014.

If you liked this post, you should really check out my upcoming book, Prototyping Forms. Just like this, only more and better!