HTML tutorial - Forms

Navigation

Skip navigation.

Site search

Site navigation

HTML tutorial

Printing

Other tutorials

Forms

Forms are used to allow the user to provide information that can be sent to the server. They are also often used as a way for a user to provide information to be used by JavaScripts. To make the most use of forms, you will have to have access to server side scripting, which can process the information. Some hosting services may provide automated scripts that can process the form data and send it as an email.

Different server side scripting implementations deal with these input values in different ways. You will need to check with the documentation of the relevant server side environment to see how to use the submitted values.

Forms are defined using the FORM tag, and there are a few attributes you will need to define. Firstly, you will need to say what method you want the form to use. There are two methods that are used with forms, and your server side environment may place restrictions on which you can use:

GET
This is the most common method, and is most useful for smaller forms, where the user will not provide much information. When they submit the form, it will build a page address that contains all of the form information, encoded as part of the address:
http://example.com/foo.php?bar=some+data&baz=test%2B%3D%5Bdata%5D
Because the information is encoded in the URL, it is limited to the length of a URL. In many browsers, this is 4 KB (and due to the encoding, this means about 3 KB of actual form data).
POST
This is the smarter method. You will need to use this if any of your inputs are file inputs, or if you might need to be able to handle more than 3 KB of form data. Alternatively, you might want to use this if you need to keep your page addresses clean. Note that if you use this method, your users will not be able to bookmark the resulting page addresses, so I advise you not to use this method for search engines. This method also can cause problems when using back and forward buttons.

The other attribute you will need to specify is the action attribute. This is the location of the page that you want to send the form information to. The syntax is similar to the HREF of a link, except that it should always point to a page, not to any internal links.

<form method="get" action="processform.php">

If one of your inputs is a file, you must also set the ENCTYPE attribute to "multipart/form-data". Normally, you do not need to set this attribute, as it will assume its default value of "application/x-www-form-urlencoded".

The FORM element is block level, but it cannot contain inline elements or text directly. It must contain other block level elements, such as paragraphs. These can then contain all the desired form controls.

Form controls

There are several types of form controls, and they serve different purposes. They may appear differently in different browsers, this is intentional, so that they can fit in with the theme of the relevant system. These inputs each have their own behaviour, and although it is possible to use scripts to make some of them behave like others (such as making checkboxes behave like radio inputs), I advise you not to attempt to do this, as it will confuse your users.

Inputs are all inline elements. The inputs created with the INPUT element do not have a closing tag. All other input element types require a closing tag.

The majority of inputs are created with the INPUT tag, and the type of input is specified using the TYPE attribute. All inputs accept the NAME attribute. This will be used as the name of the variable that will be sent to the server, with the value specified (normally) by the user.

Forms can contain as many form controls as they need, including multiple submit or reset buttons. These form controls can be in any order that you choose, but of course, you should try to make it make sense.

When a form is submitted to a server, the values of all relevant form controls are sent to the server as a text string. The server side script may convert them into other data types, and in the form control they may appear to look like numbers or timestamps, but as long as they are held in a form control, they are held as a string.

Text inputs

The basic text input is created using the INPUT tag by setting the TYPE to "text". The initial contents of the input can be specified using the VALUE attribute. If you do not include this attribute, or if you specify an empty value, there will be no contents by default. The text input is a single line input accepting any normal text characters, but not linebreaks. If the contents are too large to fit, the input will scroll, usually without a visible scrollbar.

<p><input type="text" name="street" value="Some initial content"></p>

That will create an input like this:

There are a few other attributes that are of interest here. These are mainly the MAXLENGTH, READONLY and DISABLED attributes. MAXLENGTH can be used to specify the maximum number of characters that the user is allowed to enter in the input (such as maxlength="50").

READONLY does exactly what it says. This is most useful when working with scripts, with the idea being that you can put new content in the input, but the user cannot change it (although they can usually select text in it). I advise you not to overuse this, since it looks like a normal input and may confuse the user when it fails to respond. DISABLED is useful for a similar reason because it can be changed with script (for example, when another input is changed). This has the additional benefit that the input looks like it is disabled so that it will not confuse the user. I advise you to only set these attributes using scripts - otherwise if the script is not able to run for whatever reason, the inputs will be unusable. These attributes do not need a value, you only have to write the attribute name:

<input type="text" name="street" disabled>

You can also set the size attribute, but since that is display related, it is much better to set the width from CSS. Two other attributes may be of use. These are the TABINDEX and ACCESSKEY attributes. TABINDEX expects an integer value, and can be used to alter the sequence that the tab key uses to step between inputs, if their layout is not the same as the order they are defined in the source. However, since the layout changes depending on the CSS, this attribute is much less useful.

The ACCESSKEY attribute allows you to specify a key that can be used as a shortcut to focus the input. Different browsers will expect a different key combination to activate it, and often they will conflict with the browser's own shortcuts. In my opinion, the accesskey attribute is a nice idea, but fairly useless in practice. However it is there if you want to use it.

Password inputs

This is functionally and syntactically identical to a normal text input. The only difference is that a password input does not display the typed characters that it contains. Instead, it displays a hashed version of the value, typically with the characters replaced by asterisk ('*') characters.

This is created using the INPUT element with the TYPE attribute to "password".

<p><input type="password" name="theirkey" value="Content"></p>

That will create an input like this:

Textareas

A textarea is a larger version of a text input that can contain multiple lines of text, including linebreaks. Most browsers will display a scrollbar if the contents are too large for the textarea.

Textareas are created using the TEXTAREA tag. This requires a closing tag, and has no VALUE attribute. Instead, the default value is written in between the opening and closing tags. It requires that you provide the ROWS and COLS attributes, which give a suggestion for an initial size (based on the number of characters that should be displayed vertically and horizontally). This is a little unusual, since it forces you to specify display related information in the HTML, but you can always override them using the height and width styles in CSS.

Most other attributes, such as DISABLED and ACCESSKEY are available, but MAXLENGTH is not.

<textarea name="comments" rows="3" cols="30">This is the initial content of the textarea.
Generally, browsers will wrap it if needed, and linebreaks will also be displayed.</textarea>

That will create an input like this:

Select inputs

Select inputs are also known as dropdown menus, list boxes or combo boxes. They provide an input with a number of options that the user can select.

These are the most complicated of all the inputs, and they have a variety of different ways that they can be configured. They are also well known as being difficult to style. Most browsers allow you to colour the background and text of the SELECT element, and some also allow you to specify the same for the OPTION elements. Some may allow a little more, but in general you will have to accept the limitations. SELECT inputs accept the TABINDEX attribute, and SELECT, OPTGROUP and OPTION elements all accept the DISABLED attribute.

Select inputs are created using the SELECT element, and this requires a closing tag. The options are created using the OPTION element. These have an optional closing tag, and as always, I advise you to always include it. In general the SELECT element only needs a NAME attribute. The OPTION elements will usually have a VALUE attribute (this will be what is sent to the server as the value of the input, if the user selects that option). If there is no value, then the content of the option will be used as the value. One option may also have the SELECTED attribute set to tell the browser to pre-select that option. If no option has this attribute, most browsers will pre-select the first option.

<select name="theirchoice">
  <option>First choice</option>
  <option value="val2" selected>Second choice</option>
  <option value="val3">Third choice</option>
</select>

That will create an input like this:

Options can also be grouped into subsections, using the OPTGROUP element. This can only be put directly into the SELECT element. It cannot be put inside another OPTGROUP (this will change in future versions of HTML, and most browsers already allow it, but for now, it is not valid). Most browsers display an OPTGROUP as an indented section with a title (that cannot be selected). Internet Explorer 5 on Mac and the Links browser family are the only browsers I know that display it as a hierarchical menu. The OPTGROUP element uses LABEL attribute to define what title should be displayed, and requires a closing tag.

<select name="theirchoice">
  <option value="val1">First choice</option>
  <optgroup label="Subsection 1">
    <option value="val2" selected>Second choice</option>
    <option value="val3">Third choice</option>
  </optgroup>
  <optgroup label="Subsection 2">
    <option value="val4">Forth choice</option>
    <option value="val5">Fifth choice</option>
  </optgroup>
</select>

That will create an input like this:

Select inputs can be made into a scrolling list by setting the SIZE attribute to more than 1. The options list no longer drops down in the same way, and instead, it becomes a scrolling list showing the number of lines that you specify.

<select name="theirchoice" size="3">
  <option value="val1">First choice</option>
  <option value="val2" selected>Second choice</option>
  <option value="val3">Third choice</option>
  <option value="val4">Fourth choice</option>
  <option value="val5">Fifth choice</option>
</select>

That will create an input like this:

It is also possible to allow more than one input to be selected at a time by including the MULTIPLE attribute (another one of those attributes that does not need a value). If you include this attribute, then more than one option can have the SELECTED attribute. Typically, the user can then use the Ctrl/Cmd and Shift modifier keys to select multiple options.

<select name="theirchoice" size="3" multiple>
  <option value="val1">First choice</option>
  <option value="val2" selected>Second choice</option>
  <option value="val3" selected>Third choice</option>
  <option value="val4">Fourth choice</option>
  <option value="val5">Fifth choice</option>
</select>

That will create an input like this:

It is possible to set the SIZE to 1 on a multiple select input, to end up with something that looks like spin buttons. However, I advise you never to use this, because it does not automatically select options as you spin (so you have to spin to an option then click on it), meaning that its behaviour is unpredictable and very confusing for users.

Radio buttons

Radio buttons allow you to specify several different options, where only one can be selected at a time. This is similar to options in a basic select input, except that radio buttons can be put anywhere in the form, and do not have to be close together. Most browsers display radio inputs as either a small circle (with a dot in the middle of a selected button), or as a punched in/out diamond.

A radio button is created using the INPUT element, by setting the TYPE attribute to "radio". Radio buttons are put into groups by giving them the same NAME attribute, and you can have multiple radio groups in a form. To pre-select a radio input, set the CHECKED attribute on the desired input (this is another attribute that does not need a value). You should never attempt to pre-select more than one radio input in a group. Note that if you do not pre-select any radio input in a group, some browsers will not pre-select any, while others may pre-select the first one. For this reason, I advise you to always pre-select one input in each radio group you create.

Each radio input should have its VALUE attribute set, as that is what will be sent to the server if that input is selected. They will also accept many of the common attributes, such as DISABLED and ACCESSKEY.

<ul>
  <li><input name="vehicle" type="radio" value="cars"> Car
  <ul>
    <li><input name="cartype" type="radio" value="small" checked> 2 door</li>
    <li><input name="cartype" type="radio" value="medium"> 4 door</li>
    <li><input name="cartype" type="radio" value="large"> 17 door</li>
  </ul>
  </li>
  <li><input name="vehicle" type="radio" value="busses" checked> Bus</li>
  <li><input name="vehicle" type="radio" value="trains"> Train</li>
</ul>

That will create inputs like this:

Checkboxes

Checkboxes offer a simple interface, where the user can either select the option or not. If it is selected, then the value will be sent to the server when the form is submitted. Checkboxes cannot be grouped, and normally, they will not share the same name (it is possible for them to share the name, but the server side script will have to be capable of understanding multiple values for the same variable).

A checkbox is created using the INPUT element, by setting the TYPE attribute to "checkbox". To pre-select a checkbox, set the CHECKED attribute.

Each checkbox should have its VALUE attribute set, as that is what will be sent to the server if that input is selected. If the checkbox is not selected, the browser will either pass an empty value to the server, or not pass the variable at all. They will also accept many of the common attributes, such as DISABLED and ACCESSKEY.

<ul>
  <li><input name="car" type="checkbox" value="1" checked> Car</li>
  <li><input name="bus" type="checkbox" value="1" checked> Bus</li>
  <li><input name="train" type="checkbox" value="1"> Train</li>
</ul>

That will create inputs like this:

File inputs

This allows the user to choose a file that will be uploaded to the server. There are obvious security issues here, so in order to prevent pages uploading files without permission, browsers will not allow HTML or script to set the initial value of the input. In order to make sure that the user is aware of the input type, the wording used by the input also cannot be changed. Different browsers will have their own layout for the input. Most browsers on Windows will have what looks like a text input, with either a "Choose" or "Browse" button. Many browsers on Mac will have only a button with "Choose" on it. Some Linux browsers will use only a button as well.

Browsers will have several ways to prevent users from being tricked into filling in a file input. Some may prevent pasting into the input, and some will not allow scripting events to be used to trigger the file choosing functionality. Some browsers will not allow scripts to read the value (or maybe only the file name, not the path). Some may reset the input if a script triggers the file chooser. Most browsers only allow very limited styling of file inputs. This is all intentional, and I advise you not to attempt to use any tricks to alter the display or behaviour of a file input.

A file input is created using the INPUT element, by setting the TYPE attribute to "file". They will also accept many of the common attributes, such as DISABLED and ACCESSKEY.

<input name="filetoattach" type="file">

That will create an input like this:

Submit buttons

The submit button is the button that causes the information in the form to be submitted to the server. Normally these are not given a name but if they are, then their name and value will also be sent to the server. This can be useful if you want to have multiple submit buttons, and you want the server side script to make decisions based on which button is clicked.

A submit button is created using the INPUT element, by setting the TYPE attribute to "submit". They will also accept many of the common attributes, such as DISABLED and ACCESSKEY.

<input type="submit" value="Go!">

That will create an input like this:

When a form contains at least one submit button, most browsers will automatically click the first submit button in the form if the user presses the Enter/Return key in a text or password input. Some will also do the same for radio, checkbox, select, and file inputs. Some browsers will automatically submit the form even if there is no submit button and the user presses Enter/Return in a relevant input type, but this does not work in all browsers (such as mobile, television and console browsers, as well as some desktop browsers), and should not be relied on.

Reset buttons

This will reset the form back to the state that it was in when the page was first loaded. Note that these are almost never needed, and generally are pressed by mistake when trying to submit the form (meaning that the user loses all the information they entered). You should only include a reset button if you have a real use-case for it.

A reset button is created using the INPUT element, by setting the TYPE attribute to "reset". They will also accept many of the common attributes, such as DISABLED and ACCESSKEY.

<input type="reset" value="Reset changes">

That will create an input like this:

Generic buttons

These serve no purpose on their own. The only reason they exist is to activate scripts (normally done with an onclick event handler).

A generic button is created using the INPUT element, by setting the TYPE attribute to "button". They will also accept many of the common attributes, such as DISABLED and ACCESSKEY.

<input type="button" value="Run script" onclick="alert('Hello');">

That will create an input like this:

Smarter buttons

The basic button input is fairly limited, since it can only contain text. The BUTTON element is much more advanced, as it can contain virtually any content, including block and inline elements, such as lists or images. The limitation is that it cannot contain forms or form controls, links, or image maps. It requires a closing tag. Some old browsers (such as Netscape 4) do not support this element.

The BUTTON element accepts the usual NAME attribute, and has a VALUE attribute that will be sent to the server in the same way as with a normal submit button. By setting the TYPE attribute to "submit", "reset" or "button", you can choose if it should be a submit, reset or generic button. It will also accept many of the common attributes, such as DISABLED and ACCESSKEY.

<button type="submit">
  <ul>
    <li>Inside the button</li>
    <li>Also inside the button</li>
  </ul>
  <p><img src="someimage.png" alt=""></p>
</button>

That will create an input like this:

Image inputs

These are a special kind of submit button, that use an image instead of a button interface. Clicking the image will submit the form. If the input is given a name, then when the image is clicked, the coordinates of the click are sent to the server using the name of the input. For example, if it is given the name "thesub", and you click 47 pixels from its left edge, and 8 pixels from its top edge, then the server will be sent thesub.x=47 and thesub.y=8

An image input is created using the INPUT element, by setting the TYPE attribute to "image". You will then need to set the SRC and ALT attributes, just like with a normal image. It will also accept many of the common attributes, such as DISABLED and ACCESSKEY.

<input type="image" src="someimage.png" alt="Submit">

That will create an input like this:

Hidden inputs

Sometimes it is necessary to pass values to a form as if the inputs had been filled in by a user, but without the user seeing those options.

An example of this would be a form that spans multiple pages, where the user fills in a page at a time, then moves on to the next page. You could use hidden inputs to pass the values from each page into the next page, so that the last page actually contains all the values, but the user only sees a few of them. Another example is the search form on this page. The search engine for this site allows you to search sections, but on this page, you do not see the options to choose sections. I use hidden inputs to pass the section selections (so that it only searches the tutorials by default). The search results page uses checkboxes instead, so you can choose which sections to search.

An hidden input is created using the INPUT element, by setting the TYPE attribute to "hidden". Set the NAME and VALUE attributes to say what value the input represents.

<input type="hidden" name="firstname" value="Mark &quot;Tarquin&quot;">

That will create an input that is invisible.

Labels

On their own, some inputs are a little small, and difficult for users to interact with. For example, a checkbox is just a small input, but it usually has a large amount of text associated with it. Often it is useful to have the text be a proper label, where clicking the text is the same as clicking the input. This is done using the inline LABEL element. In theory you should be able to just wrap this around an input and the text, but some browsers do not understand this, so it is better to use the alternative.

Firstly give the input an ID attribute. Usually this can be the same as the name attribute, but note that two elements must never share the same ID (so radio inputs will each need their own ID, which cannot be the same as the NAME attribute). Now create the LABEL element and give it a FOR attrible, whose value matches the ID of the input that it should relate to. It will also accept the ACCESSKEY attribute. The closing tag is required.

You can associate as many labels as needed with each form control, but each label can only be associated with one form control. Some browsers will not allow labels to be associated with file inputs (for security reasons).

<ul>
  <li><input name="whatcar" id="whatcar" type="checkbox" value="1">
  <label for="whatcar">Car</label></li>
  <li><input name="whatedition" id="edition1" type="radio" value="1" checked>
  <label for="edition1">First edition</label></li>
  <li><input name="whatedition" id="edition2" type="radio" value="2">
  <label for="edition2">Second edition</label></li>
</ul>

That would create this (try clicking the words to see what happens):

Fieldsets

Fieldsets allow you to group form controls into sections. For example, you may want to put a set of options into a group, so they appear separated from the main part of the form, but they are still used by it. To do this, place all of the relevant form controls inside a FIELDSET element (which requires a closing tag).

All FIELDSET elements need to have a LEGEND element, containing the title for the fieldset. This should be the first element inside the fieldset, and is an inline element. It accepts the optional ACCESSKEY attribute. The closing tag is required.

The fieldset is usually displayed as a thin border surrounding the inputs, with the legend written on top of the border.

<fieldset>
  <legend>Options</legend>
  <ul>
    <li><input name="alpha" type="checkbox" value="1"> Alpha</li>
    <li><input name="beta" type="checkbox" value="1"> Beta</li>
    <li><input name="gamma" type="checkbox" value="1"> Gamma</li>
  </ul>
</fieldset>

That would create this:

Options
  • Alpha
  • Beta
  • Gamma

Fieldsets can be nested as needed.

<form method="get" action="/search">
  <fieldset>
    <legend>Search</legend>
    <p>
      <input type="text" name="searchforthis">
      <input type="submit" value="Search">
    </p>
    <fieldset>
      <legend>Search sections</legend>
      <ul>
        <li><input name="searchsc1" type="checkbox" value="1" checked> Section 1</li>
        <li><input name="searchsc2" type="checkbox" value="1"> Section 2</li>
        <li><input name="searchsc3" type="checkbox" value="1"> Section 3</li>
      </ul>
    </fieldset>
  </fieldset>
</form>

That would create this:

Search

Search sections
  • Section 1
  • Section 2
  • Section 3

A complete example

Yes, a complete example would be nice, so here goes:

<form method="post" action="feedback.php" enctype="multipart/form-data">
  <fieldset>
    <legend>Personal</legend>
    <p><label for="persname">Name:
    <input type="text" name="persname" id="persname" maxlength="50"></label></p>
    <p><label for="perspswd">Password:
    <input type="password" name="perspswd" id="perspswd"></label></p>
    <fieldset>
      <legend>History</legend>
      <p><label for="waystohear">How did you hear about us:
      <select name="waystohear" id="waystohear" size="3" multiple>
        <option value="search" selected>Search engine</option>
        <option value="friend">Word of mouth</option>
        <option value="advert">Ads</option>
      </select></label></p>
      <p><label for="prevvisit">How many times have you visited:
      <select name="prevvisit" id="prevvisit">
        <option value="1" selected>1</option>
        <option value="2">2</option>
        <option value="3+">3 or more</option>
      </select></label></p>
    </fieldset>
  </fieldset>
  <fieldset>
    <legend>Subscribe</legend>
    <ul>
      <li><label for="subs1"><input type="checkbox" name="subs1" id="subs1">
      Email spam</label></li>
      <li><label for="subs2"><input type="checkbox" name="subs2" id="subs2">
      Postal spam</label></li>
    </ul>
  </fieldset>
  <fieldset>
    <legend>Comments</legend>
    <ul>
      <li><label for="cmnttype1"><input type="radio" name="cmnttype" id="cmnttype1" checked>
      About the site</label></li>
      <li><label for="cmnttype2"><input type="radio" name="cmnttype" id="cmnttype2">
      About the company</label></li>
    </ul>
    <p><label for="perscmnt">Let us know what you think:</label></p>
    <p><textarea rows="3" cols="30" name="perscmnt" id="perscmnt">Hi,
I like your &quot;stuff&quot;.</textarea></p>
    <p><label for="cmntfile">Upload comments as a file:
    <input type="file" name="cmntfile" id="cmntfile"></label></p>
  </fieldset>
  <p>
    <input type="reset" value="Reset">
    <button type="submit">Submit</button>
  </p>
</form>

That would create this form:

Personal

History

Subscribe
Comments

Is there more?

There is more, but not widely supported. Web Forms 2.0, now included in HTML 5, adds many more input types and abilities. Most notably, it adds number inputs, date inputs, time inputs, slider inputs ('range' - like a volume control), text inputs with auto-completion, output status fields, and others. As well as that, they are self validating, so you can specify the format of the input, and it will require the user to enter valid data. There are also many other features, such as nested forms, multiple file uploads, and ability to automatically repeat sets of inputs.

One of the extra useful features is that older browsers that do not understand the specific type of input will fall back to a basic text input, meaning that you can use the newer input types, and the form will work in browsers that support it, and still function as a basic form in browsers that do not.

Currently, Web Forms 2.0 is supported by Opera 9, and olav.dk has a behaviour file that can be used to add support for Internet Explorer 6+. Safari/Chrome also supports the range input.

Last modified: 13 February 2011

  1. Previous
  2. Next
This site was created by Mark "Tarquin" Wilton-Jones.
Don't click this link unless you want to be banned from our site.