Basic Interactivity

image of Web form

Looking for the lessons? Get started!

An overview of constructing forms in your Web pages.

The entire Web Design Principles section can be accessed through the menu below.

Unfortunately, not everyone's browser will support the spiffy JavaScript menu behind that innocent-looking button. If your browser won't display the menu, just click on the button and you'll be taken to a separate page with the entire menu displayed in clear, non-JavaScript HTML.

[F]orms are an essential part of web design and development. From small login forms to detailed administration panels, forms are one of the most important interactive elements of your web site or application. They're the carriers of data and — if you’ll pardon the courier's cliché — should be handled with care. — Bolton, Connell, and Featherstone

A lot of good Web designers get confused when it comes to creating and designing forms. The markup is so different from most other HTML as to be almost a different codeset entirely, the function is very different, and CSS doesn't work very well on some elements of forms. But these are essential if you want your site visitors to be able to interact with your site — submit data, take surveys, send e-mails securely, buy things with credit cards, and so forth. And forms have other uses as well, particularly in making navigational schemes.

Much of the content on this page is based on material written by Jennifer Niederst Robbins, with additional input from Tizag, EchoEcho, Jukka Korpela, HTML Dog, and Web Design Group (WDG).

Forms use controls, which come in several varieties, including buttons, text fields, and scrolling menus. You place form controls on the page using somewhat different HTML markup than you've used until now.

What really sets forms apart is how the data they collect is processed: it isn't done by the browser or the user's computer, but by the server itself. Whereas almost everything else on this site is considered client-side coding (i.e. through the browser and/or the user's own computer), forms are server-side coding, because they send information for processing to the server, which in turn funnels it to you.

I'm not even going to touch the server end of forms. That's a body of knowledge that others cover better than I ever could. But I can, and will, show you how to create forms in your Web pages.

You'll use some or all of these elements in creating a form:

form
establishes the form itself
input
creates controls
button
basic input button
textarea
creates a "text field" that allows data input, usually typed information
select
multiple-choice menu or scrolling list
option
an option inside a select list
optgroup
defines a group of options
label
attaches information to controls
fieldset
groups related controls and labels
legend
assigns a caption to a fieldset

Confused yet? I know I was. I've created and revamped a number of forms in my time, and will no doubt do more in the future, but I still get a bit itchy working with them. They're just so … alien as compared to regular HTML and CSS markup!

Don't worry, by the time we're done, you'll be on speaking terms with forms.

The Form Element

At its most basic, the form element is a container, like the div element:

<form>
   ... 
</form>

The form element — a block-level element — contains any of a large number of attributes, many of which you've not seen until now. You can use some of these, none of these, or all of these (if you want to get rowdy):

  • ID, class, style, title (the "core" attributes)
  • onreset and onblur
  • accept
  • action (a required attribute)
  • enctype
  • method
  • name (deprecated in XHTML, but we don't care about that)
  • target

While the form element can contain a number of different HTML content types, such as text, images, tables, and so forth, but the function is to serve as a container for form controls — checkboxes, menus, text fields, buttons, and so forth, all to be used for entering information. Moreover, the form element allows the contained information to interact with the program that actually processes the information.

Don't do what a lot of novice designers do and try to "nest" form elements. They don't work right when nested. You can, however, have multiple (separate) forms in a single document.

The idea behind a form is to allow the user to enter information, press the "Submit" button, and watch as the browser shuttles the information off to the server. Behind the scenes, the browser sorts the information into name/value pairs, encodes it for transfer, and sends it to the server. The server works its voodoo and sends the information to you, the site owner or manager.

Cribbing shamelessly from Robbins's book, here's an example of what a simple form might look like:

<h2>Sign my guestbook!</h2>
<form action="/cgi-bin/guestbook.pl" method="get">
   <p>First name: <input type="text" name="first"><br>
   Nickname: <input type="text" name="nickname"><br>
   <input type="submit"> <input type="reset"></p>
</form>

which gives us:

Sign my guestbook!

First name:
Nickname:

(Play with the form all you like, this is an example only. Nothing works.)

Let's deconstruct this piece of code and see what's what.

First, the entire thing is contained inside a form element. The form element has an attribute, which looks something like a URL but really isn't. The /cgi-bin/guestbook.pl is a Perl script that activates through a CGI, or "Common Gateway Interface," script. You don't need to know this stuff (at the moment). Just notice that the form takes an action that activates a server-side script, and makes the whole thing work.

It also includes the method element, which uses the get attribute to properly submit the information the user inputs. I won't get into the difference between the get attribute and the other attribute used by method, the post attribute. Basically, unless the server setup requires it, or if you're sending a lot of form data, you'll use the get attribute.

Next we have an ordinary p, or paragraph, element that contains two input elements, both with the text and name attributes. Bet you can figure this out … The two input elements accept text input, specifically requiring a first name and a nickname, respectively.

Then you have two buttons controlled by, again, the input element, but this time with the submit and reset attributes respectively.

Close the form element and that's it!

(Notice you don't close the input element. It's a standalone tag.)

Form Controls

You have a number of form controls (sometimes called "widgets") at your disposal. Almost all of them, excluding the submit and reset elements, require a name attribute to make them function properly (and validate). Whatever you choose as your name, don't use spaces:

<input type="text" name="your nickname"> Wrong!

Use underscores or periods instead.

It's plain from the example above that whatever you choose as your name will be used as the "name" of the input variable. The content entered by the user becomes assigned to that variable. The name attribute is critical for passing information along to the site owner or wherever it's going.

There are a number of controls, all using the input element. You can have:

  • single-line text entry fields;
  • password entry fields;
  • hidden controls;
  • checkboxes;
  • "radio" buttons;
  • submit and reset buttons;
  • file upload mechanisms; and
  • custom and image buttons.

All of these are controlled by the type attribute.

The input element has the following possible attributes (some have their possible values shown):

  • ID, class, style, title (the "core" attributes)
  • onselect, onchange
  • alt="text"
  • accept="MIME type"
  • accesskey="character"
  • checked="checked"
  • disabled="disabled"
  • maxlength="number"
  • name="text" (note this is required on everything except submit and reset)
  • readonly="readonly"
  • size="number"
  • src="URL"
  • tabindex="number"
  • type the default value; includes:
  • text
  • password
  • checkbox
  • radio
  • submit
  • reset
  • file
  • hidden
  • image
  • button
  • value="text"

Text input

The simplest kind of text input is a text field:

<form action="/cgi-bin/guestbook.pl" method="get">
   <p><input type="text" name="first"></p>
   ...
</form>

which gives us:

(Note that the input element, being an inline element, requires being put inside a block-level element such as a p or div.)

The text element can have any of a number of attributes:

  • ID, class, style, title (the "core" attributes)
  • accesskey, tabindex, onfocus, onblur (the "focus" attributes)
  • disabled="disabled"
  • maxlength=number
  • name="text" (required)
  • readonly="readonly"
  • size="number"
  • value="text"

The maxlength attribute decides how long the input field will be. If you don't specify a number (measured in characters), the value will default to an unlimited number (not recommended).

<form action="/cgi-bin/guestbook.pl" method="get">
   <p><input type="text" name="first" maxlength="20"></p>
   ...
</form>

which gives us:

It doesn't look any different, but you can now type up to 20 characters into the field. Try it.

The actual size can be controlled by the size attribute. The default is 20 characters, but you can change it:

<form action="/cgi-bin/guestbook.pl" method="get">
   <p><input type="text" name="first" maxlength="20" size="40"></p>
   ...
</form>

which gives us:

That's a good bit longer.

You can set text to appear in the field using the value attribute:

<form action="/cgi-bin/guestbook.pl" method="get">
   <p><input type="text" name="first" maxlength="20" size="40" value="enter text here"></p>
   ...
</form>

which gives us:

Password text entry

A password field, using the type="password" setting, works the same as a text entry field, except it hides the text being typed into the field and replaces it with asterisks. Like so:

<form action="/cgi-bin/guestbook.pl" method="get">
   <p><input type="password" name="first" maxlength="20" size="40"></p>
   ...
</form>

which gives us:

Doesn't look any different, until you type something into the field.

The password element can have any of a number of attributes. much like the text element:

  • ID, class, style, title (the "core" attributes)
  • accesskey, tabindex, onfocus, onblur (the "focus" attributes)
  • disabled="disabled"
  • maxlength=number
  • name="text" (required)
  • readonly="readonly"
  • size="number"
  • value="text"

Don't make the mistake of thinking that the password element is any sort of encryption. All it does is obscure the characters you type from being seen by people looking over your shoulder. Or, as Tizag reminds us:

Do not use the password feature for security purposes. The data in the password field is not encrypted and is not secure in any way.

Hidden entry

Hidden inputs, which are handled with the type="hidden" attribute, add control(s) that aren't displayed in the browser, but are supplied to the form processor when the form is submitted. These are used primarily to submit labels used by the scripts to sort forms. Users can't see hidden inputs.

Hidden controls can have a few attributes:

  • accesskey="character"
  • tabindex="number"
  • name="text" (required)
  • value="text"

If you need a hidden entry in your form, you'd add it like this:

<input type="hidden" name="extra_info" value="important">

Checkbox

Checkboxes are simple "yes/no, on/off" choices toggled by the user. They're good for multiple-choice questions that can have more than one answer, because more than one checkbox can be selected at a time. When a form is submitted, only the "on" values are reported.

Here's an example:

<form action="#" method="get">
   <p><input type="checkbox" name="dogbreed" value="labrador">Labrador retriever</p>
   <p><input type="checkbox" name="dogbreed" value="beagle">Beagle</p>
   <p><input type="checkbox" name="dogbreed" value="shepherd">German shepherd</p>
   <p><input type="checkbox" name="dogbreed" value="dalmatian">Dalmatian</p>
   <p><input type="submit"> <input type="reset"></p>
</form>

giving us this:

Which dog breed(s) do you prefer?

Labrador retriever

Beagle

German shepherd

Dalmatian

Note the name is the same for all four choices, which allows for the multiple-choice aspect of the checkbox element.

Checkbox controls can have a number of attributes:

  • ID, class, style, title (the "core" attributes)
  • accesskey, tabindex, onfocus, onblur (the "focus" attributes)
  • align ("left", "right", "top", "texttop", "middle", "absmiddle", "baseline", "bottom")
  • checked="checked">
  • disabled="disabled"
  • name="text" (required)
  • readonly="readonly"
  • value="text"

"Radio" buttons

Older folks reading this will quickly figure out why they're called radio buttons, signified by type="radio". For the rest of you, keep reading.

Radio buttons are even simpler than checkboxes. They can be toggled on or off, yes or no, but unlike the checkbox, multiple radio button inputs can have only one choice — when you choose one, the others are not selected, and when you choose another, the first selection is "unchosen."

Older car radios had pushbuttons for selecting a radio station: when you pushed one radio button to choose a station, the previous selection button popped out, "deselecting" that station.

Here's one of the old fellows now. I think I drove this car at some point.

Anyway, here's how you might use one. Let's stick with the dog breed question.

<form action="#" method="get">
   <p><input type="radio" name="dogbreed" value="labrador">Labrador retriever</p>
   <p><input type="radio" name="dogbreed" value="beagle">Beagle</p>
   <p><input type="radio" name="dogbreed" value="shepherd">German shepherd</p>
   <p><input type="radio" name="dogbreed" value="dalmatian">Dalmatian</p>
   <p><input type="submit"> <input type="reset"></p>
</form>

gives us this:

Which dog breed do you prefer? (Choose only one.)

Labrador retriever

Beagle

German shepherd

Dalmatian

Try clicking the different buttons to see how they work.

Radio controls can have a number of attributes:

  • ID, class, style, title (the "core" attributes)
  • accesskey, tabindex, onfocus, onblur (the "focus" attributes)
  • checked="checked">
  • disabled="disabled"
  • name="text" (required)
  • readonly="readonly"
  • value="text"

Submit button

The submit element, created with type="submit", creates a "Submit" button. Easy enough.

The submit element can have a number of attributes:

  • ID, class, style, title (the "core" attributes)
  • accesskey, tabindex, onfocus, onblur (the "focus" attributes)
  • disabled="disabled"
  • readonly="readonly"
  • value="text"

By default, the button uses the word "Submit" as its text. You can use the value="text" attribute to change the text to something else:

<form action="#" method="get">
   <p><input type="submit" value="Click this puppy!"></p>
</form>

gives us

Reset button

This button is implemented almost identically to the submit button, except it resets the form to its original state. Users can fix errors before submitting the form.

Like the submit element, the reset element can have a number of attributes:

  • ID, class, style, title (the "core" attributes)
  • accesskey, tabindex, onfocus, onblur (the "focus" attributes)
  • disabled="disabled"
  • value="text"

Again, you can use the the value="text" attribute to change the text to something else:

<form action="#" method="get">
   <p><input type="reset" value="I goofed, try again"></p>
</form>

gives us

Custom button

The button element doesn't have a function of its own. Rather, other programs and scripts use it for their own purposes. Like the submit and reset elements, the button element can have its text determined by the value="text" attribute:

<form action="#" method="get">
   <p><input type="button" value="Something cool will happen"></p>
</form>

gives us

Like the others, the button element can have a number of attributes:

  • ID, class, style, title (the "core" attributes)
  • accesskey, tabindex, onfocus, onblur (the "focus" attributes)
  • align ("left", "right", "top", "texttop", "middle", "absmiddle", "baseline", "bottom")
  • disabled="disabled"
  • name="text"
  • value="text"

Those align attributes are most confusing. EchoEcho gives us an explanation of each one, both textual and visual.

Image button

You can, within limits, use images to make a submit button.

Using code something like this:

<form action="#" method="get">
   <p><input type="image" src="../images/submit.png" alt="send info"></p>
</form>

gives us this:

(Button created in about one minute through the free Button Generator. Beats firing up Photoshop for this particular task.)

The image element also has a number of attributes:

  • ID, class, style, title (the "core" attributes)
  • accesskey, tabindex, onfocus, onblur (the "focus" attributes)
  • align ("top", "middle", "bottom")
  • alt="text"
  • disabled="disabled"
  • name="text" (required)
  • src="URL"

File selection

Users can, if you wish, submit external files through a form. The form control includes a text field and a "Browse" button that allows them to search their computer for the file.

You have to add the following attributes to your form element:

<form enctype="multipart/form-data" action="a URL that will receive the form">

Doing something like this:

<form enctype="multipart/form-data" action="http://www.example.com/cgi/handle">
   <p>Send your file and the accompanying information:</p>
   <p><input type="file" size="28"></p>
</form>

gives us this:

Send your file and the accompanying information:

(Oddly enough, Safari and Chrome don't display the information box beside the file lookup. Opera, Firefox, and even Internet Explorer display the information box properly. Hmmmm.)

The image element also has a number of attributes:

  • ID, class, style, title (the "core" attributes)
  • accesskey, tabindex, onfocus, onblur (the "focus" attributes)
  • accept="MIME type"
  • disabled="disabled"
  • maxlength="number"
  • name="text" (required)
  • readonly="readonly"
  • size="number"
  • value="text"

Multiline Text Areas

Using the textarea property allows you to create a larger text field that users can enter in whatever typed information they choose.

This one isn't an attribute for input, but stands alone.

Using code something like this:

<form action="#" method="get">
   <p><textarea name="infofield" rows="4" cols="45">Fill in the information here.</textarea></p>
</form>

gives us this:

The rows and cols attributes control the number of rows and columns in the text field (the columns are measured in characters, i.e. 45 "cols" equals a width of 45 characters). You'll have to play with it in your designs to get the field to the size you want.

Typing more than the text field size contains is okay, the textarea field just gives itself scrollbars.

The textarea element has a number of attributes:

  • ID, class, style, title (the "core" attributes)
  • accesskey, tabindex, onfocus, onblur (the "focus" attributes)
  • onselect, onchange
  • disabled="disabled"
  • readonly="readonly"
  • cols="number" (required)
  • name="text" (required)
  • rows="number" (required)

Custom Buttons

The button element defines a custom button that functions like those created with the input element. However, the button has no defined properties or functions, but is reliant upon outside agencies such as a JavaScript or another HTML command to function.

I won't go into further information on this element right now. Forms are hard enough without adding another layer of confusion …

This creates a menu that is small in area but packs a lot of options "behind the scenes," as it were. You can create either a pull-down menu or a scrolling list of options. The select element works to contain any number of option elements, and can also contain one or more optgroups, that define a logical group of option elements.

The select element contains a number of attributes.

  • ID, class, style, title (the "core" attributes)
  • onfocus, onblur, onchange
  • disabled="disabled"
  • multiple="multiple"
  • name="text" (required)
  • size="number">
  • tabindex="number"

The option element contains a number of attributes.

  • ID, class, style, title (the "core" attributes)
  • disabled="disabled"
  • label="text"
  • selected="selected"
  • value="text"

The optgroup elements contains a few attributes.

  • disabled="disabled"
  • label="text" (required)

That was confusing … Let's see if we can illustrate what we're talking about here.

Let's start with a simple pull-down menu:

<form action="#" method="get">
   <p>What is your favorite dog breed?</p>
   <p><select name="dogbreed">
      <option>Labrador Retriever</option>
      <option>Beagle</option>
      <option>German Shepherd</option>
      <option>Dalmatian</option>
   </select></p>
</form>

gives us:

What is your favorite dog breed?

If you want to have an option besides the first item in the list selected, use the selected attribute:

<option selected="selected">Dalmatian</option>

changes the menu display:

What is your favorite dog breed?

It only takes a slight addition to the code to create a scrolling menu instead of a pull-down menu.

You'll add the size and multiple attributes to the select element. Like so:

<select name="dogbreed" size="4" multiple="multiple">

thus giving us:

What is your favorite dog breed?

The size value of 4 determines how many option values will display in the menu. Note the scrollbar; you can have fifty option values if you want, and only four will display. Here's a menu showing ten option values:

What is your favorite dog breed?

Using the optgroup element is for when you want to subdivide your option values into smaller groups. For example, we might want to create two groups of dogs, "toys" (the little guys) and "hounds." We make a few replacements in our represented breeds, use the optgroup element to make some changes, and we get:

What is your favorite dog breed?

Form Accessibility

Having your forms accessible to disabled and impaired users is a necessity. Many of these options improve usability for all site visitors, not just those with special needs.

More about accessibility.

Label

Probably the easiest thing to do is add a label element to your form fields. These make it easier for people using speech readers and other devices to handle your forms.

The label element, unlike some used in forms, requires an ending tag: </code>.

Although there is more than one way to add a label element to your code, this is the easiest. Just insert the label element into your form like so, using the above password code as an example:

<form action="/cgi-bin/guestbook.pl" method="get">
   <p><label>Password: <input type="password" name="first" maxlength="20" size="40"></label></p>
   ...
</form>

which gives us:

Useful for anyone to have that label there, not just the visually impaired.

Title

Adding a title attribute to form fields is good for speech readers and everyone else, as non-impaired users will have the title display as a "tooltip" with the control. Like so:

<form action="/cgi-bin/guestbook.pl" method="get">
   <p><label>Password: <input type="password" name="first" maxlength="20" size="40" title="password"></label></p>
   ...
</form>

gives us:

Hover your mouse over the input field to see the tooltip.

Disabled

Including the disabled attribute doesn't allow its element to be selected. Those of us who become more sophisticated in our form construction can use this attribute to disallow the selection of particular options depending on choices made earlier in the form.

Readonly

Similar to disabled, the readonly attribute doesn't let the user change the value of the particular form field, though it can be selected.

Other elements

Other optional elements for accessibility and usability include:

  • fieldset
  • legend
  • accesskey and tabindex

I'm not going to go into these here.

Styling Forms with CSS

One of the biggest "cottage industries" in HTML/CSS tutorials involves styling forms with CSS. There's a limit to what you can do to style a form element, but generally, you can wreak drastic improvements on your forms with a judiciously applied bit of styling. Certainly the fonts, colors, and size can all be changed to suit your purposes. Most form elements accept the ID, class, and style attributes, so you can attach font, color, and size stylings that way. The label, fieldset, and legend elements can also be used for styling purposes.

If we take a simple submit button and style it (you would use your external stylesheet, but if you peek at my code, you'll see I'm cheating with inline styling), you get the following:

Using padding, margins, floats, and other CSS techniques can help you align your forms nicely, either horizontally or vertically, something else good designers routinely do to enhance the visual appeal of their forms.

Form Resources

There are a lot of online resources for building forms, some quite sophisticated. Wufoo is probably one of the best ones available, and it's free to boot.