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!
(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?
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.)
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:
(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 …
Menus Using the Select Element
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:
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:
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:
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:
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:
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.
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.