How to structure an HTML form

  • Revision slug: HTML/Forms/How_to_structure_an_HTML_form
  • Revision title: How to structure an HTML form
  • Revision id: 314001
  • Created:
  • Creator: Jeremie
  • Is current revision? No
  • Comment

Revision Content

When building an HTML form, structuring it properly is an important step. It's important for 2 reason: to guaranty that your form will be usable and to make it accessible. Accessibility of HTML forms is a key point and we'll see how to make such a form accessible. It's no big deal but there is a few tricks to know.

HTML Forms are one of the more complex structure in HTML due to their flexibility. By mixing the dedicated elements and attributes you can build any kind of basic form. That said, it worth noting that some people found HTML forms quite rough and simplistic. It's true that it exist some more richer form technologies such as XForms but those kind of forms are unfortunately not implemented among browsers. So most of the time, we rely on JavaScript to enhance HTML Forms. In this article we'll see in detail how to use all the HTML forms elements, if you want to know more about building custom form widget, you can read the article: How to build custom form widgets

Global Structure

the {{HTMLElement("form")}} element

The {{HTMLElement("form")}} element is the element that formally defines a form, and its attributes define the way this form behave. Each time you want to create an HTML form, you must start it by using this element. Many assistive technologies or browsers plugin are able to discover the {{HTMLElement("form")}} elements and can implement special hooks to make them easier to use by users.

Note that it's strictly forbidden to nested a form in a form. This has no sens and it can behave in an unpredictable way among browsers.

The {{HTMLElement("form")}} element support the following attributes, all optional:

Attributes for the {{HTMLElement("form")}} element
Attribut name Default value Description
{{htmlattrxref("accept-charset","form")}} UNKNOWN A spaces delimited list of character encodings that the server accepts. The default value is the special string UNKNOWN, and in that case the encoding corresponds to the encoding of the document containing the form element
{{htmlattrxref("action","form")}}   The URI of a web page that processes the information submitted via the form
{{htmlattrxref("autocomplete","form")}} on Indicates whether widgets in this form can by default have their values automatically completed by the browser. This attribute can take two values: on or off.
{{htmlattrxref("enctype","form")}} application/x-www-form-urlencoded When the value of the method attribute is post, this attribute is the MIME type of content that is used to submit the form to the server. Possible values are:
  • application/x-www-form-urlencoded
  • multipart/form-data: Use this value if you are using an {{HTMLElement("input")}} element with the type attribute set to file.
  • text/plain
{{htmlattrxref("method","form")}} get The HTTP method that the browser uses to submit the form. This attribute can take two values: get or post.
{{htmlattrxref("name","form")}}   The name of the form. It must be unique among the forms in a document and not the empty string. It's usually recommended to use the id attribute instead.
{{htmlattrxref("novalidate","form")}} (false) This boolean attribute indicates that the form is not to be validated when it is submitted.
{{htmlattrxref("target","form")}} _self A name or keyword indicating where to display ({{HTMLElement("iframe")}}, tab, window, etc.) the response that is received after submitting the form. The following keywords are available as a value for this attribute:
  • _self: Load the response into the same browsing context ({{HTMLElement("iframe")}}, tab, window, etc.) as the current one.
  • _blank: Load the response into a new browsing context.
  • _parent: Load the response into the HTML5 parent browsing context of the current one. If there is no parent, this option behaves the same way as _self.
  • _top: Load the response into the top-level browsing context (that is, the browsing context that is an ancestor of the current one, and has no parent). If there is no parent, this option behaves the same way as _self.

Note that it's always possible to use a form widget outside of a {{HTMLElement("form")}} element but in that case, this form widget has nothing to do with form. It can be convenient to use such widget outside of a form but it means that you have special plan for this widget and it will do nothing by itself, You'll have to customize it's behavior with JavaScript. Technically speaking, HTML5 introduce the form attribute on HTML form elements. It should allow to explicitly bound an element with a form even if this element is out of the {{ HTMLElement("form") }} element. Unfortunately, for the time being, the implementation of this feature among browser is not good enough to relay on it trustfully.

The {{HTMLElement("fieldset")}} and {{HTMLElement("legend")}} elements

The {{HTMLElement("fieldset")}} element is a convenient way to create groups of widgets that share the same purpose. A {{HTMLElement("fieldset")}} element can be labeled with a {{HTMLElement("legend")}} element. The {{HTMLElement("legend")}} element formally describe the purpose of the {{HTMLElement("fieldset")}} element. Many assistive technologies will use the {{HTMLElement("legend")}} element as if it were part of the label of each widget inside the corresponding {{HTMLElement("fieldset")}} element. For example, some screen readers such as Jaws or NVDA will pronounce the legend's content before pronouncing the label of each widget.

Here is a little example:

<form>
    <fieldset>
        <legend>Fruit juice size</legend>
        <p>
            <input type="radio" name="size" id="size_1" value="small" />
            <label for="size_1">Small</label>
        </p>
        <p>
            <input type="radio" name="size" id="size_2" value="medium" />
            <label for="size_2">Medium</label>
        </p>
        <p>
            <input type="radio" name="size" id="size_3" value="large" />
            <label for="size_3">Large</label>
        </p>
    </fieldset>
</form>

With this example, a screen reader will pronounce "Fruit juice size small" for the first widget, "Fruit juice size medium" for the second and "Fruit juice size large" for the third.

This use case in the previous example is one of the most important. Each time you have a set of radio button, you can be sure that they can be nested inside a {{HTMLElement("fieldset")}} element. There is other use cases and in general the {{HTMLElement("fieldset")}} element can also be used to strongly section a form. Because of it's influence over assistive technology, the {{HTMLElement("fieldset")}} element is one of the key element to build accessible forms, however it is your responsibility to not abuse it. If possible, each time you build a form, try to listen its rendering inside a screen reader. If it sounds odd it's a good hint that your form structure need to be enhanced.

The {{HTMLElement("fieldset")}} element support the following specific attribute:

Attributes for the {{HTMLElement("fieldset")}} element
Attribute name Default value Description
{{htmlattrxref("disabled","fieldset")}} (false) If this Boolean attribute is set, the form controls that are its descendants, except descendants of its first optional {{ HTMLElement("legend") }} element, are disabled, i.e., not editable. They won't received any browsing events, like mouse clicks or focus-related ones. Often browsers display such controls as gray.

The {{HTMLElement("label")}} element

The {{HTMLElement("label")}} element is the formal way to define a label for an HTML form widget. This is the most important element if you want to build accessible forms.

The {{HTMLElement("label")}} element support the following attributes:

Attributes for the {{HTMLElement("label")}} element
Attribute name Default value Description
{{htmlattrxref("for","label")}}   The ID of a labelable widget in the same document as the label element. The first such element in the document with an ID matching the value of the for attribute is the labeled widget for this label element.

A {{HTMLElement("label")}} element is bound to its widget with the for attribute. The for attribute actually reference the id attribute of the corresponding widget. A widget can be nested inside its {{HTMLElement("label")}} element but even in that case, it is considered best practice to set the for attribute because some assistive technologies do not understand implicit relation between label and widget.

Note that even without considering assistive technologies, having a formal label set for a given widget allow the users to click on the label to activate the corresponding widget in all browsers. This is especially useful for radio button and checkbox.

<form>
    <p>
        <input type="checkbox" id="taste_1" name="taste_cherry" value="1">
        <label for="taste_1">I like cherry</label>
    </p>
    <p>
        <label for="taste_2">
            <input type="checkbox" id="taste_2" name="taste_banana" value="1">
            I like banana
        </label>
    </p>
</form>

Some assistive technologies can have trouble handling multiple labels for a single widget, therefor it's considered best practice to nest a widget inside its corresponding element to build accessible form.

Let's consider this example:

<form>
    <p>Required fields are followed by <strong><abbr title="required">*</abbr></strong>.</p>
    
    <p>
        <label for="name">
            <span>Name: </span>
            <input type="text" id="name" name="username" required />
            <strong><abbr title="required">*</abbr></strong>
        </label>
    </p>
    
    <p>
        <label for="birth">
            <span>Date of birth: </span>
            <input type="text" id="birth" name="userbirth" maxlength="10" /> <em>formated as mm/dd/yyyy</em>
        </label>
    </p>
</form>

In this example, the first paragraph define the rule for required elements. It must be at the beginning to be sure that assistive technologies such as screen reader will display or vocalize it to the user before he founds a required element. That way, he always know what he have to do.

The first form element is required so its label contain at the same time its "true" label and the mention that indicate it's a required element. That way, a screen reader will vocalize the label as "Name star" or "Name required" (this depend of each screen reader settings but it's always consistent with what was vocalized in the first paragraph). If you had had two labels, there is no guarantee that the user would have been informed that this element was required.

It's the same thing about the second form element. With this technique, you are sure that the user is informed about the right date format.

The {{HTMLElement("output")}} element

This element is used to store the output of a calculation. It formally defines a relation between the fields use to get the piece of data required to perform the calculation. It is also understood as a live region by some assistive technologies (which means that when the content of the <output> element change, the assistive technology is aware of that change and can react to it).

The {{HTMLElement("output")}} element support the following attributes:

Attributes for the {{HTMLElement("output")}} element
Attribute name Default value Description
{{htmlattrxref("for","output")}}   A spaces delimited list of IDs of other elements, indicating that those elements contributed input values to (or otherwise affected) the calculation.

Common HTML structure used with forms

Beyond the structure specific to HTML forms, it's good to remember that forms are plain HTML. This means that you can use all the power of HTML to structure an HTML form.

As you can see in the examples, It's common practice to wrap a label and its widget with a {{HTMLElement("p")}} or a {{HTMLElement("div")}} element.

In addition to the {{HTMLElement("fieldset")}} element, it's also common practice to use HTML titles and sectioning to structure a complex form.

HTML list are also often used when we have to deal with checkbox and radio button.

Let's see an example with a simplified payment form:

<form>
    <h1>Payment form</h1>
    <p>Required fields are followed by <strong><abbr title="required">*</abbr></strong>.</p>
    
    <section>
        <h2>Contact information</h2>
        
        <fieldset>
            <legend>Title</legend>
            <ul>
                <li>
                    <label for="title_1">
                        <input type="radio" id="title_1" name="title" value="M." />
                        Mister
                    </label>
                </li>
                <li>
                    <label for="title_2">
                        <input type="radio" id="title_2" name="title" value="Ms." />
                        Miss
                    </label>
                </li>
            </ul>
        </fieldset>
        
        <p>
            <label for="name">
                <span>Name: </span>
                <input type="text" id="name" name="username" required />
                <strong><abbr title="required">*</abbr></strong>
            </label>
        </p>
        
         <p>
            <label for="mail">
                <span>E-mail: </span>
                <input type="email" id="mail" name="usermail" required />
                <strong><abbr title="required">*</abbr></strong>
            </label>
        </p>
    </section>
    
    <section>
        <h2>Payment information</h2>
        
        <p>
            <label for="card">
                <span>Card type:</span>
                <select id="card" name="usercard">
                    <option value="visa">Visa</option>
                    <option value="mc">Mastercard</option>
                    <option value="amex">American Express</option>
                </select>
            </label>
        </p>
        <p>
            <label for="number">
                <span>Card number:</span>
                <input type="text" id="number" name="cardnumber" required />
                <strong><abbr title="required">*</abbr></strong>
            </label>
        </p>
        <p>
            <label for="date">
                <span>Expiration date:</span>
                <input type="text" id="date" name="expiration" required />
                <strong><abbr title="required">*</abbr></strong>
                <em>formated as mm/yy</em>
            </label>
        </p>
    </section>
    
    <section>
        <p>
            <button>Validate the payment</button>
        </p>
    </section>
</form>

See this form in action: [Add a link to the form]

HTML widgets

When you build a form, you need to use some widgets to collect the data from the user. In this article we will see how to display those widgets, if you want to know more about the way those widgets work, it is detailed in the article: The native form widgets.

The {{HTMLElement("input")}} element

This element is kind of special, it can be almost everything. By simply setting it's type attribute, it can change radically. To make things a little simpler, the value for the type attribute can be categorize in four kind of rendering: single line text fields, controls without text input, time and date controls and buttons. Because of this polymorphism, the {{HTMLElement("input")}} element support many attributes but it is difficult to know which are relevant and which are required. It all depends on the value of the type attribute.

This is all summarized in the following table (for a full list of all attributes, visit the page for the {{HTMLElement("input")}} element) :

Value of the type attribute Description Required attributes Relevant attributes
Single line text fields
text This is the most basic text field. the value text for the type attribute is the default value of this attribute.   {{htmlattrxref("autocomplete","input")}}, {{htmlattrxref("list","input")}}, {{htmlattrxref("maxlength","input")}}, {{htmlattrxref("pattern","input")}}, {{htmlattrxref("placeholder","input")}}, {{htmlattrxref("readonly","input")}}, {{htmlattrxref("required","input")}}, {{htmlattrxref("size","input")}}, {{htmlattrxref("spellcheck","input")}}
email A field for editing one or more e-mail addresses.   {{htmlattrxref("autocomplete","input")}}, {{htmlattrxref("list","input")}}, {{htmlattrxref("maxlength","input")}}, {{htmlattrxref("multiple","input")}}, {{htmlattrxref("pattern","input")}}, {{htmlattrxref("placeholder","input")}}, {{htmlattrxref("readonly","input")}}, {{htmlattrxref("required","input")}}, {{htmlattrxref("size","input")}}
password The value of this text field is obscured   {{htmlattrxref("autocomplete","input")}}, {{htmlattrxref("list","input")}}, {{htmlattrxref("maxlength","input")}}, {{htmlattrxref("readonly","input")}}, {{htmlattrxref("required","input")}}, {{htmlattrxref("size","input")}}
search A field for entering search strings   {{htmlattrxref("autocomplete","input")}}, {{htmlattrxref("autosave","input")}}, {{htmlattrxref("list","input")}}, {{htmlattrxref("maxlength","input")}}, {{htmlattrxref("pattern","input")}}, {{htmlattrxref("placeholder","input")}}, {{htmlattrxref("readonly","input")}}, {{htmlattrxref("required","input")}}, {{htmlattrxref("size","input")}}, {{htmlattrxref("spellcheck","input")}}
tel A field for editing a phone number.   {{htmlattrxref("autocomplete","input")}}, {{htmlattrxref("list","input")}}, {{htmlattrxref("maxlength","input")}}, {{htmlattrxref("pattern","input")}}, {{htmlattrxref("placeholder","input")}}, {{htmlattrxref("readonly","input")}}, {{htmlattrxref("required","input")}}, {{htmlattrxref("size","input")}}
url A field for editing an absolute URL.   {{htmlattrxref("autocomplete","input")}}, {{htmlattrxref("list","input")}}, {{htmlattrxref("maxlength","input")}}, {{htmlattrxref("pattern","input")}}, {{htmlattrxref("placeholder","input")}}, {{htmlattrxref("readonly","input")}}, {{htmlattrxref("required","input")}}, {{htmlattrxref("size","input")}}
Controls without text input
checkbox Display a checkbox   {{htmlattrxref("checked","input")}}, {{htmlattrxref("required","input")}}
color A control to specify a color   {{htmlattrxref("autocomplete","input")}}, {{htmlattrxref("list","input")}}, {{htmlattrxref("required","input")}}
file A control that lets the user select a file.   {{htmlattrxref("accept","input")}}, {{htmlattrxref("multiple","input")}}, {{htmlattrxref("required","input")}}
hidden A control that is not displayed, but whose value is submitted to the server.    
number A control for entering a floating point number.   {{htmlattrxref("autocomplete","input")}}, {{htmlattrxref("list","input")}}, {{htmlattrxref("max","input")}}, {{htmlattrxref("min","input")}}, {{htmlattrxref("readonly","input")}}, {{htmlattrxref("required","input")}}, {{htmlattrxref("step","input")}}
radio Display a radio button   {{htmlattrxref("checked","input")}}, {{htmlattrxref("required","input")}}
range A control for entering a number whose exact value is not important.   {{htmlattrxref("autocomplete","input")}}, {{htmlattrxref("list","input")}}, {{htmlattrxref("max","input")}}, {{htmlattrxref("min","input")}}, {{htmlattrxref("required","input")}}, {{htmlattrxref("step","input")}}
Time and date controls
date A control for entering a date (year, month, and day, with no time).   {{htmlattrxref("autocomplete","input")}}, {{htmlattrxref("list","input")}}, {{htmlattrxref("max","input")}}, {{htmlattrxref("min","input")}}, {{htmlattrxref("readonly","input")}}, {{htmlattrxref("required","input")}}
datetime A control for entering a date and time (hour, minute, second, and fraction of a second) based on UTC time zone.   {{htmlattrxref("autocomplete","input")}}, {{htmlattrxref("list","input")}}, {{htmlattrxref("max","input")}}, {{htmlattrxref("min","input")}}, {{htmlattrxref("readonly","input")}}, {{htmlattrxref("required","input")}}
datetime-local A control for entering a date and time, with no time zone.   {{htmlattrxref("autocomplete","input")}}, {{htmlattrxref("list","input")}}, {{htmlattrxref("max","input")}}, {{htmlattrxref("min","input")}}, {{htmlattrxref("readonly","input")}}, {{htmlattrxref("required","input")}}
month A control for entering a month and year, with no time zone.   {{htmlattrxref("autocomplete","input")}}, {{htmlattrxref("list","input")}}, {{htmlattrxref("max","input")}}, {{htmlattrxref("min","input")}}, {{htmlattrxref("readonly","input")}}, {{htmlattrxref("required","input")}}
time A control for entering a time value with no time zone.   {{htmlattrxref("autocomplete","input")}}, {{htmlattrxref("list","input")}}, {{htmlattrxref("max","input")}}, {{htmlattrxref("min","input")}}, {{htmlattrxref("readonly","input")}}, {{htmlattrxref("required","input")}}
week A control for entering a date consisting of a week-year number and a week number with no time zone.   {{htmlattrxref("autocomplete","input")}}, {{htmlattrxref("list","input")}}, {{htmlattrxref("max","input")}}, {{htmlattrxref("min","input")}}, {{htmlattrxref("readonly","input")}}, {{htmlattrxref("required","input")}}
Buttons
button A push button with no default behavior.   {{htmlattrxref("formaction","input")}}, {{htmlattrxref("formenctype","input")}}, {{htmlattrxref("formmethod","input")}}, {{htmlattrxref("formnovalidate","input")}}, {{htmlattrxref("formtarget","input")}}
image A graphical submit button. {{htmlattrxref("src","input")}}, {{htmlattrxref("alt","input")}} {{htmlattrxref("width","input")}}, {{htmlattrxref("height","input")}}, {{htmlattrxref("formaction","input")}}, {{htmlattrxref("formenctype","input")}}, {{htmlattrxref("formmethod","input")}}, {{htmlattrxref("formnovalidate","input")}}, {{htmlattrxref("formtarget","input")}}
reset A button that resets the contents of the form to default values.   {{htmlattrxref("formaction","input")}}, {{htmlattrxref("formenctype","input")}}, {{htmlattrxref("formmethod","input")}}, {{htmlattrxref("formnovalidate","input")}}, {{htmlattrxref("formtarget","input")}}
submit A button that submits the form.   {{htmlattrxref("formaction","input")}}, {{htmlattrxref("formenctype","input")}}, {{htmlattrxref("formmethod","input")}}, {{htmlattrxref("formnovalidate","input")}}, {{htmlattrxref("formtarget","input")}}

If for some reason, the value set in the type attribute is not supported by a browser, it render the {{HTMLElement("input")}} element as if the value was text.

Even if the {{HTMLElement("input")}} element is a powerful tool, it can not do everything and there is a few other elements to handled those cases.

The {{HTMLElement("textarea")}} element

This element is dedicated to the multiline text field. It works exactly as a single line text field except that it allows line break in the text typed by the user. It also accept a few extra attributes to control it's rendering on several lines:

Attributes for the {{HTMLElement("textarea")}} element
Attribute name Default value Description
{{htmlattrxref("cols","textarea")}} 20 The visible width of the text control, in average character widths.
{{htmlattrxref("rows","textarea")}}   The number of visible text lines for the control.
{{htmlattrxref("wrap","textarea")}} soft Indicates how the control wraps text. Possible values are: hard or soft

Note that the {{HTMLElement("textarea")}} element work a little bit differently than the {{HTMLElement("input")}} element. The {{HTMLElement("input")}} element is a self closing element, which means that it can not contain any child elements. On the contrary, the {{HTMLElement("textarea")}} element is a regular element that can contain text content children.

This has two impact:

  •  If you want to define a default value for an {{HTMLElement("input")}} element, you have to use the value attribute, but if you want to define a default value for a {{HTMLElement("textarea")}} element, you have to write this value between the starting tag and the closing tag of the element
  • Because of its nature the {{HTMLElement("textarea")}} element only accept text content which means that any HTML content put inside a {{HTMLElement("textarea")}} element is rendered as if it was plain text content.

In the following example, the {{HTMLElement("textarea")}} elements will be rendered exactly the same:

<form>
    <p>
        <label for="text_1">With regular HTML</label><br>
        <textarea id="text_1" name="regular"><p>I'm a paragraphe</p></textarea>
    </p>
    <p>
        <label for="text_2">With escaped HTML</label><br>
        <textarea id="text_2" name="escaped">&lt;p&gt;I'm a paragraphe&lt;/p&gt;</textarea>
    </p>
    <p>
        <button>Send me</button>
    </p>
</form>

The {{HTMLElement("select")}}, {{HTMLElement("option")}} and {{HTMLElement("optgroup")}} elements

The {{HTMLElement("select")}} element is especially made to build select boxes (sometimes also known as combo boxes). A select box is a widget that allow a user to choose one or more predefine values. The difference between a single value select box and a multiple value select box will be detailed in the article: The native form widget.

Each value inside the select box is define with an {{HTMLElement("option")}} element and those elements can be grouped inside {{HTMLElement("option")}} elements.

Let's take an example:

<form>
    <p>
        <label for="myFruit">Pick a fruit</label>
        <select id="muFruit" name="fruit">
            <!-- There is a trick here you think you'll pick 
                 a banana but you'll eat an Orange >:-) -->
            <option value="orange">Banana</option>
            <option>Cherry</option>
            <optgroup label="berries">
                <option>Blueberry</option>
                <option>Raspberry</option>
                <option>Strawberry</option>
            </optgroup>
        </select>
    </p>
</form>

If an {{HTMLElement("option")}} element is set with a value attribute, it's the value of this attribute which is sent. If the value attribute is omitted, it's the content of the {{HTMLElement("option")}} element that is sent as the value for the select box.

On the {{HTMLElement("optgroup")}} element, the label attribute will be display before the values, but even if it looks more or less like an option, it is not selectable.

Attributes for the {{HTMLElement("option")}} element
Attribute name Default value Description
{{htmlattrxref("label","option")}}   This attribute is text for the label indicating the meaning of the option. If the label attribute isn't defined, its value is that of the element text content.
{{htmlattrxref("selected","option")}} (false) If present, this Boolean attribute indicates that the option is initially selected.
Attributes for the {{HTMLElement("optgroup")}} element
Attribute name Default value Description
{{htmlattrxref("label","optgroup")}}   The name of the group of options. This attribute is mandatory.

The {{HTMLElement("datalist")}} element

This  element extend the existing widgets by providing some preset value for a  given widgets. The most know use case for this is an autocompletion  list for text fields. The values available are set with {{HTMLElement("option")}} elements within the {{HTMLElement("datalist")}} element.

To bind a widget with a {{HTMLElement("datalist")}} element you have to use the list attribute on the target widget. The list attribute is referencing the value of the id attribute of the {{HTMLElement("datalist")}} element to use.

The  {{HTMLElement("datalist")}} element is a very new addition to HTML forms so there is still some browser that do not support it. To handle this, here is a little trick to have a nice fallback for those browsers:

<form>
    <p>
        <label for="myFruit">What is your favorite fruit?</label>
        <input type="text" id="myFruit" name="fruit" list="fruitList" />
        
        <datalist id="fruitList">
            <label for="suggestion">or pick a fruit</label>
            <select id="suggestion" name="altFruit">
                <option value="banana">Banana</option>
                <option value="cherry">Cherry</option>
                <option value="strawberry">Strawberry</option>
            </select>
        </datalist>
    </p>
</form>

On the one hand, browsers that support the {{HTMLElement("datalist")}} element will ignore all the elements that are not {{HTMLElement("option")}} element and will work as expected. On the other hand, browsers that do not support the {{HTMLElement("datalist")}} element will display the label and the select box. Of course, there is other way to handle the lack of support for the {{HTMLElement("datalist")}} element but it require the use of JavaScript which is not necessarily always reliable.

[Add a screenshot of this example]

The {{HTMLElement("meter")}} and {{HTMLElement("progress")}} elements

Those two elements are a way to graphically represent a given numeric value. The difference between the two elements is mainly semantic:

  • The {{HTMLElement("meter")}} element represent a static value and its relative position between a min and a max value
  • The {{HTMLElement("progress")}} element represent a changing value that evolved between a min value and a max value. It worth noting that animating the change of value have to be down with JavaScript. The element itself does not have any mechanism to do it on its own.

Du to their nature those element support a set of specific attributes:

Attributes for the {{HTMLElement("meter")}} element
Attribute name Default value Description
{{htmlattrxref("min","meter")}} 0 The lower numeric bound of the measured range.
{{htmlattrxref("max","meter")}} 1 The upper numeric bound of the measured range.
{{htmlattrxref("low","meter")}} the min value The upper numeric bound of the low end of the measured range.
{{htmlattrxref("high","meter")}} the max value The lower numeric bound of the high end of the measured range.
{{htmlattrxref("optimum","meter")}}   The optimal numeric value.
Attributes for the {{HTMLElement("progress")}} element
Attribute name Default value Description
{{htmlattrxref("max","progress")}}   This attribute describes how much work the task indicated by the {{HTMLElement("progress")}} element requires.

The {{HTMLElement("button")}} element

A {{HTMLElement("button")}} element is the easiest way to create a form button. A button can be of three type defined by the value of the type attribute:

  • A submit button: it sends the form's data to the web page defined by the action attribute of the <form> element.
  • A reset button: it resets all the form widgets to their default value immediately. From a UX point of view it is considered bad practice to use such a button.
  • An anonymous button: This kind of button just do nothing. It is used with Javascript to build custom buttons.
Attributes for the {{HTMLElement("button")}} element
Attribute name Default value Description
{{htmlattrxref("type","button")}} submit The type of the button. Possible values are: button, reset or submit
{{htmlattrxref("formaction","button")}}   If the button is a submit button, the value of this attribute overrides the value of the action attribute on the {{HTMLElement("form")}} element.
{{htmlattrxref("formenctype","button")}}   If the button is a submit button, the value of this attribute overrides the value of the enctype attribute on the {{HTMLElement("form")}} element.
{{htmlattrxref("formmethod","button")}}   If the button is a submit button, the value of this attribute overrides the value of the method attribute on the {{HTMLElement("form")}} element.
{{htmlattrxref("formnovalidate","button")}}   If the button is a submit button, the value of this attribute overrides the value of the novalidate attribute on the {{HTMLElement("form")}} element.
{{htmlattrxref("formtarget","button")}}   If the button is a submit button, the value of this attribute overrides the value of the target attribute on the {{HTMLElement("form")}} element.

Technically speaking, there is almost no difference between a button define with the {{HTMLElement("button")}} element or the {{HTMLElement("input")}} element. The only noticeable difference is the label of the button itself. Within an {{HTMLElement("input")}} element, the label can only be character data, on the contrary, within a {{HTMLElement("button")}} element, the label can be plain HTML which means it can be styled accordingly.

For historical reason the {{HTMLElement("button")}} element was no used really often and in many form, developers prefer to use the button made with the {{HTMLElement("input")}} element. This is due to a bug in legacy version of Internet Explorer (IE). In IE6 and IE7, if you add a name and a value attribute to a {{HTMLElement("button")}} element, they do not send the content of the value attribute but the raw content of the button instead. This has been fixed since IE8 so there is currently no reason to avoid using the {{HTMLElement("button")}} element.

Common attributes

The elements used to define form widgets can have some specific attributes. However, there is a set of common attributes to all this elements that allow you to have some control over those widgets. Here is a list of those attributes:

Attribute name Default value Description
autofocus (false) This Boolean attribute lets you specify that the element should have input focus when the page loads, unless the user overrides it, for example by typing in a different control. Only one form-associated element in a document can have this attribute specified.
disabled (false) This Boolean attribute indicates that the user cannot interact with the element. If this attribute is not specified, the element inherits its setting from the containing element, for example {{HTMLElement("fieldset")}}; if there is no containing element with the disabled attribute set, then the element is enabled.
form   The form element that the button is associated with. The value of the attribute must be the id attribute of a {{HTMLElement("form")}} element in the same document. In theory, it allow to set a form widget outside of a {{HTMLElement("form")}} element. In practice there is no browser which support that feature.
name   The name of the element, which is submitted with the form data.
value   The initial value of the element.

Using ARIA to structure HTML forms

ARIA is a W3C Candidate Recommendation which is an addition to HTML to improve the accessibility of rich Internet application. ARIA can be used in many cases beyond HTML form. We will discuss its use in more detail in the "How to build custom form widgets" article, but there is some basics that are good to know.

Before going further, it worth noting that the support of ARIA among browsers and assistive technologies is far from perfect, but it's improving. Just to understand the issue, when a browser encounter an ARIA attribute, it have to send information to the OS accessibility layer. Not all browser are good at doing this cross platform. The assistive technologies, on their own, have to connect themselves to the OS accessibility layer to handle the information that come from the browsers. Surprisingly, not all assistive technologies do it well. So using ARIA does not mean that your web application will be accessible, but it means that you do your best to achieve this. Unfortunately, for the time being, ARIA remain a best effort technology but it's always better than nothing.

If you want to dig into using ARIA with HTML forms, feel free to read the related section in the ARIA documentation.

The aria-labelledby attribute

This attribute is a convenient way to define a label without using the {{HTMLElement("label")}} element. The attribute is set on the widget element and reference the id attribute of the element to use as a label.

<form>
    <p id="fruitLabel">What's your favorite fruit</p>
    <p>
        <input type="text" name="fruit" aria-labelledby="fruitLabel">
    </p>
</form>

Conceptually it's the opposite of the for attribute on the {{HTMLElement("label")}} element. With the for attribute, you reference the id of the widget but with the aria-labbeldby attribute, you reference the id of the label.

The aria-describedby attribute

This attribute works like the aria-labelledby attribute. The difference is mainly semantic. A label define the essence of an object, while a description provides more information that the user might need.

The aria-label attribute

This attribute is used when there is no explicit label in the DOM for a given widget. It allow to give a widget that will be passed to assitive technologies but without the need to create a DOM node for this.

<form>
    <p>
        <input type="search" name="q" aria-label="Search" />
        <input type="submit" value="Go" />
    </p>
</form>

The role attribute

This is the most important ARIA attribute. It allow to give specific semantic understandable by assitive technologies to a given HTML element. There is many roles available and some of them are dedicated to form widgets.

ARIA try to provide a specific semantic for widget that are currently not existing in HTML as well as for existing ones. We will see in detail how to use those roles in the article: How to build custom form widgets.

Those roles for form widgets are :

It's also worth noting that it existing what is called composite role :

If those roles are extremely useful, know that there is more, ARIA is a very large specification and to dig into it can help you in many way beyond HTML forms.

Conclusion

You now have all the knowledge to properly structure your HTML Forms, the next article will dig into implementation detail and functional expectation: The native form widgets
 

Revision Source

<p>When building an HTML form, structuring it properly is an important step. It's important for 2 reason: to guaranty that your form will be usable and to make it accessible. Accessibility of HTML forms is a key point and we'll see how to make such a form accessible. It's no big deal but there is a few tricks to know.</p>
<p>HTML Forms are one of the more complex structure in HTML due to their flexibility. By mixing the dedicated elements and attributes you can build any kind of basic form. That said, it worth noting that some people found HTML forms quite rough and simplistic. It's true that it exist some more richer form technologies such as <a href="/en-US/docs/XForms" title="/en-US/docs/XForms">XForms</a> but those kind of forms are unfortunately not implemented among browsers. So most of the time, we rely on JavaScript to enhance HTML Forms. In this article we'll see in detail how to use all the HTML forms elements, if you want to know more about building custom form widget, you can read the article: <a href="/en-US/docs/HTML/Forms/How_to_build_custom_form_widgets" title="/en-US/docs/HTML/Forms/How_to_build_custom_form_widgets">How to build custom form widgets</a></p>
<h2 id="Global_Structure">Global Structure</h2>
<h3 id="the_.7B.7BHTMLElement(.22form.22).7D.7D_element">the {{HTMLElement("form")}} element</h3>
<p>The {{HTMLElement("form")}} element is the element that formally defines a form, and its attributes define the way this form behave. Each time you want to create an HTML form, you must start it by using this element. Many assistive technologies or browsers plugin are able to discover the {{HTMLElement("form")}} elements and can implement special hooks to make them easier to use by users.</p>
<div class="note">
  Note that it's strictly forbidden to nested a form in a form. This has no sens and it can behave in an unpredictable way among browsers.</div>
<p>The {{HTMLElement("form")}} element support the following attributes, all optional:</p>
<table>
  <caption>
    Attributes for the {{HTMLElement("form")}} element</caption>
  <thead>
    <tr>
      <th scope="col">Attribut&nbsp;name</th>
      <th scope="col">Default&nbsp;value</th>
      <th scope="col">Description</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="white-space: nowrap;">{{htmlattrxref("accept-charset","form")}}</td>
      <td><code>UNKNOWN</code></td>
      <td>A spaces delimited list of character encodings that the server accepts. The default value is the special string <code>UNKNOWN</code>, and in that case the encoding corresponds to the encoding of the document containing the form element</td>
    </tr>
    <tr>
      <td>{{htmlattrxref("action","form")}}</td>
      <td>&nbsp;</td>
      <td>The URI of a web page that processes the information submitted via the form</td>
    </tr>
    <tr>
      <td>{{htmlattrxref("autocomplete","form")}}</td>
      <td><code>on</code></td>
      <td>Indicates whether widgets in this form can by default have their values automatically completed by the browser. This attribute can take two values: <code>on</code> or <code>off</code>.</td>
    </tr>
    <tr>
      <td>{{htmlattrxref("enctype","form")}}</td>
      <td><span style="font-family: Courier New;">application/x-www-form-urlencoded</span></td>
      <td>When the value of the <code>method</code> attribute is <span style="font-family: Courier New;">post</span>, this attribute is the <a class="external" href="http://en.wikipedia.org/wiki/Mime_type" title="http://en.wikipedia.org/wiki/Mime_type">MIME&nbsp;type</a> of content that is used to submit the form to the server. Possible values are:
        <ul>
          <li><span style="font-family: Courier New;">application/x-www-form-urlencoded</span></li>
          <li><span style="font-family: Courier New;">multipart/form-data</span>: Use this value if you are using an {{HTMLElement("input")}} element with the <code>type</code> attribute set to <em>file</em>.</li>
          <li><span style="font-family: Courier New;">text/plain</span></li>
        </ul>
      </td>
    </tr>
    <tr>
      <td>{{htmlattrxref("method","form")}}</td>
      <td><code>get</code></td>
      <td>The <a class="external" href="http://www.w3.org/Protocols/rfc2616/rfc2616.html" title="http://www.w3.org/Protocols/rfc2616/rfc2616.html">HTTP</a>&nbsp;method that the browser uses to submit the form. This attribute can take two values: <code>get</code> or <code>post</code>.</td>
    </tr>
    <tr>
      <td>{{htmlattrxref("name","form")}}</td>
      <td>&nbsp;</td>
      <td>The name of the form. It must be unique among the forms in a document and not the empty string. It's usually recommended to use the <code>id</code> attribute instead.</td>
    </tr>
    <tr>
      <td>{{htmlattrxref("novalidate","form")}}</td>
      <td>(<em>false</em>)</td>
      <td>This boolean attribute indicates that the form is not to be validated when it is submitted.</td>
    </tr>
    <tr>
      <td>{{htmlattrxref("target","form")}}</td>
      <td><code>_self</code></td>
      <td>A name or keyword indicating where to display ({{HTMLElement("iframe")}}, tab, window, etc.) the response that is received after submitting the form. The following keywords are available as a value for this attribute:<br />
        <ul>
          <li><span style="font-family: Courier New;">_self</span>:&nbsp;Load the response into the same browsing context ({{HTMLElement("iframe")}}, tab, window, etc.) as the current one.</li>
          <li><span style="font-family: Courier New;">_blank</span>: Load the response into a new browsing context.</li>
          <li><span style="font-family: Courier New;">_parent</span>:&nbsp;Load the response into the HTML5 parent browsing context of the current one. If there is no parent, this option behaves the same way as <span style="font-family: Courier New;">_self</span>.</li>
          <li><span style="font-family: Courier New;">_top</span>: Load the response into the top-level browsing context (that is, the browsing context that is an ancestor of the current one, and has no parent). If there is no parent, this option behaves the same way as <span style="font-family: Courier New;">_self</span>.</li>
        </ul>
      </td>
    </tr>
  </tbody>
</table>
<p>Note that it's always possible to use a form widget outside of a {{HTMLElement("form")}} element but in that case, this form widget has nothing to do with form. It can be convenient to use such widget outside of a form but it means that you have special plan for this widget and it will do nothing by itself, You'll have to customize it's behavior with JavaScript. Technically speaking, HTML5 introduce the <code>form</code> attribute on HTML form elements. It should allow to explicitly bound an element with a form even if this element is out of the {{ HTMLElement("form") }} element. Unfortunately, for the time being, the implementation of this feature among browser is not good enough to relay on it trustfully.</p>
<h3 id="The_.7B.7BHTMLElement(.22fieldset.22).7D.7D_and_.7B.7BHTMLElement(.22legend.22).7D.7D_elements">The {{HTMLElement("fieldset")}} and {{HTMLElement("legend")}} elements</h3>
<p>The {{HTMLElement("fieldset")}} element is a convenient way to create groups of widgets that share the same purpose. A {{HTMLElement("fieldset")}} element can be labeled with a {{HTMLElement("legend")}} element. The {{HTMLElement("legend")}} element formally describe the purpose of the {{HTMLElement("fieldset")}} element. Many assistive technologies will use the {{HTMLElement("legend")}} element as if it were part of the label of each widget inside the corresponding {{HTMLElement("fieldset")}} element. For example, some screen readers such as <a href="http://www.freedomscientific.com/products/fs/jaws-product-page.asp" rel="external" title="http://www.freedomscientific.com/products/fs/jaws-product-page.asp">Jaws</a> or <a href="http://www.nvda-project.org/" rel="external" title="http://www.nvda-project.org/">NVDA</a> will pronounce the legend's content before pronouncing the label of each widget.</p>
<p>Here is a little example:</p>
<pre class="brush:html;">
&lt;form&gt;
    &lt;fieldset&gt;
        &lt;legend&gt;Fruit juice size&lt;/legend&gt;
        &lt;p&gt;
            &lt;input type="radio" name="size" id="size_1" value="small" /&gt;
            &lt;label for="size_1"&gt;Small&lt;/label&gt;
        &lt;/p&gt;
        &lt;p&gt;
            &lt;input type="radio" name="size" id="size_2" value="medium" /&gt;
            &lt;label for="size_2"&gt;Medium&lt;/label&gt;
        &lt;/p&gt;
        &lt;p&gt;
            &lt;input type="radio" name="size" id="size_3" value="large" /&gt;
            &lt;label for="size_3"&gt;Large&lt;/label&gt;
        &lt;/p&gt;
    &lt;/fieldset&gt;
&lt;/form&gt;</pre>
<p>With this example, a screen reader will pronounce "Fruit juice size small" for the first widget, "Fruit juice size medium" for the second and "Fruit juice size large" for the third.</p>
<p>This use case in the previous example is one of the most important. Each time you have a set of radio button, you can be sure that they can be nested inside a {{HTMLElement("fieldset")}} element. There is other use cases and in general the {{HTMLElement("fieldset")}} element can also be used to strongly section a form. Because of it's influence over assistive technology, the {{HTMLElement("fieldset")}} element is one of the key element to build accessible forms, however it is your responsibility to not abuse it. If possible, each time you build a form, try to listen its rendering inside a screen reader. If it sounds odd it's a good hint that your form structure need to be enhanced.</p>
<p>The {{HTMLElement("fieldset")}} element support the following specific attribute:</p>
<table>
  <caption>
    Attributes for the {{HTMLElement("fieldset")}} element</caption>
  <thead>
    <tr>
      <th scope="col">Attribute&nbsp;name</th>
      <th scope="col">Default&nbsp;value</th>
      <th scope="col">Description</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>{{htmlattrxref("disabled","fieldset")}}</td>
      <td>(<em>false</em>)</td>
      <td>If this Boolean attribute is set, the form controls that are its descendants, except descendants of its first optional {{ HTMLElement("legend") }} element, are disabled, i.e., not editable. They won't received any browsing events, like mouse clicks or focus-related ones. Often browsers display such controls as gray.</td>
    </tr>
  </tbody>
</table>
<h3 id="The_.7B.7BHTMLElement(.22label.22).7D.7D_element">The {{HTMLElement("label")}} element</h3>
<p>The {{HTMLElement("label")}} element is the formal way to define a label for an HTML form widget. This is the most important element if you want to build accessible forms.</p>
<p>The {{HTMLElement("label")}} element support the following attributes:</p>
<table>
  <caption>
    Attributes for the {{HTMLElement("label")}} element</caption>
  <thead>
    <tr>
      <th scope="col">Attribute&nbsp;name</th>
      <th scope="col">Default&nbsp;value</th>
      <th scope="col">Description</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>{{htmlattrxref("for","label")}}</td>
      <td>&nbsp;</td>
      <td>The ID of a labelable widget in the same document as the label element. The first such element in the document with an ID matching the value of the <code>for</code> attribute is the labeled widget for this label element.</td>
    </tr>
  </tbody>
</table>
<p>A {{HTMLElement("label")}} element is bound to its widget with the <code>for</code> attribute. The <code>for</code> attribute actually reference the <code>id</code> attribute of the corresponding widget. A widget can be nested inside its {{HTMLElement("label")}} element but even in that case, it is considered best practice to set the <code>for</code> attribute because some assistive technologies do not understand implicit relation between label and widget.</p>
<p>Note that even without considering assistive technologies, having a formal label set for a given widget allow the users to click on the label to activate the corresponding widget in all browsers. This is especially useful for radio button and checkbox.</p>
<pre class="brush:html;">
&lt;form&gt;
    &lt;p&gt;
        &lt;input type="checkbox" id="taste_1" name="taste_cherry" value="1"&gt;
        &lt;label for="taste_1"&gt;I like cherry&lt;/label&gt;
    &lt;/p&gt;
    &lt;p&gt;
        &lt;label for="taste_2"&gt;
            &lt;input type="checkbox" id="taste_2" name="taste_banana" value="1"&gt;
            I like banana
        &lt;/label&gt;
    &lt;/p&gt;
&lt;/form&gt;</pre>
<p>Some assistive technologies can have trouble handling multiple labels for a single widget, therefor it's considered best practice to nest a widget inside its corresponding element to build accessible form.</p>
<p>Let's consider this example:</p>
<pre class="brush:html;">
&lt;form&gt;
    &lt;p&gt;Required fields are followed by &lt;strong&gt;&lt;abbr title="required"&gt;*&lt;/abbr&gt;&lt;/strong&gt;.&lt;/p&gt;
    
    &lt;p&gt;
        &lt;label for="name"&gt;
            &lt;span&gt;Name: &lt;/span&gt;
            &lt;input type="text" id="name" name="username" required /&gt;
            &lt;strong&gt;&lt;abbr title="required"&gt;*&lt;/abbr&gt;&lt;/strong&gt;
        &lt;/label&gt;
    &lt;/p&gt;
    
    &lt;p&gt;
        &lt;label for="birth"&gt;
            &lt;span&gt;Date of birth: &lt;/span&gt;
            &lt;input type="text" id="birth" name="userbirth" maxlength="10" /&gt; &lt;em&gt;formated as mm/dd/yyyy&lt;/em&gt;
        &lt;/label&gt;
    &lt;/p&gt;
&lt;/form&gt;</pre>
<p>In this example, the first paragraph define the rule for required elements. It must be at the beginning to be sure that assistive technologies such as screen reader will display or vocalize it to the user before he founds a required element. That way, he always know what he have to do.</p>
<p>The first form element is required so its label contain at the same time its "true" label and the mention that indicate it's a required element. That way, a screen reader will vocalize the label as "<em>Name star</em>" or "<em>Name required</em>" (this depend of each screen reader settings but it's always consistent with what was vocalized in the first paragraph). If you had had two labels, there is no guarantee that the user would have been informed that this element was required.</p>
<p>It's the same thing about the second form element. With this technique, you are sure that the user is informed about the right date format.</p>
<h3 id="The_.7B.7BHTMLElement(.22output.22).7D.7D_element">The {{HTMLElement("output")}} element</h3>
<p>This element is used to store the output of a calculation. It formally defines a relation between the fields use to get the piece of data required to perform the calculation. It is also understood as a live region by some assistive technologies (which means that when the content of the &lt;output&gt; element change, the assistive technology is aware of that change and can react to it).</p>
<p>The {{HTMLElement("output")}} element support the following attributes:</p>
<table>
  <caption>
    Attributes for the {{HTMLElement("output")}} element</caption>
  <thead>
    <tr>
      <th scope="col">Attribute&nbsp;name</th>
      <th scope="col">Default&nbsp;value</th>
      <th scope="col">Description</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>{{htmlattrxref("for","output")}}</td>
      <td>&nbsp;</td>
      <td>A spaces delimited list of IDs of other elements, indicating that those elements contributed input values to (or otherwise affected) the calculation.</td>
    </tr>
  </tbody>
</table>
<h3 id="Common_HTML_structure_used_with_forms">Common HTML structure used with forms</h3>
<p>Beyond the structure specific to HTML forms, it's good to remember that forms are plain HTML. This means that you can use all the power of HTML to structure an HTML form.</p>
<p>As you can see in the examples, It's common practice to wrap a label and its widget with a {{HTMLElement("p")}} or a {{HTMLElement("div")}} element.</p>
<p>In addition to the {{HTMLElement("fieldset")}} element, it's also common practice to use HTML titles and sectioning to structure a complex form.</p>
<p>HTML list are also often used when we have to deal with checkbox and radio button.</p>
<p>Let's see an example with a simplified payment form:</p>
<pre class="brush:html;">
&lt;form&gt;
    &lt;h1&gt;Payment form&lt;/h1&gt;
    &lt;p&gt;Required fields are followed by &lt;strong&gt;&lt;abbr title="required"&gt;*&lt;/abbr&gt;&lt;/strong&gt;.&lt;/p&gt;
    
    &lt;section&gt;
        &lt;h2&gt;Contact information&lt;/h2&gt;
        
        &lt;fieldset&gt;
            &lt;legend&gt;Title&lt;/legend&gt;
            &lt;ul&gt;
                &lt;li&gt;
                    &lt;label for="title_1"&gt;
                        &lt;input type="radio" id="title_1" name="title" value="M." /&gt;
                        Mister
                    &lt;/label&gt;
                &lt;/li&gt;
                &lt;li&gt;
                    &lt;label for="title_2"&gt;
                        &lt;input type="radio" id="title_2" name="title" value="Ms." /&gt;
                        Miss
                    &lt;/label&gt;
                &lt;/li&gt;
            &lt;/ul&gt;
        &lt;/fieldset&gt;
        
        &lt;p&gt;
            &lt;label for="name"&gt;
                &lt;span&gt;Name: &lt;/span&gt;
                &lt;input type="text" id="name" name="username" required /&gt;
                &lt;strong&gt;&lt;abbr title="required"&gt;*&lt;/abbr&gt;&lt;/strong&gt;
            &lt;/label&gt;
        &lt;/p&gt;
        
         &lt;p&gt;
            &lt;label for="mail"&gt;
                &lt;span&gt;E-mail: &lt;/span&gt;
                &lt;input type="email" id="mail" name="usermail" required /&gt;
                &lt;strong&gt;&lt;abbr title="required"&gt;*&lt;/abbr&gt;&lt;/strong&gt;
            &lt;/label&gt;
        &lt;/p&gt;
    &lt;/section&gt;
    
    &lt;section&gt;
        &lt;h2&gt;Payment information&lt;/h2&gt;
        
        &lt;p&gt;
            &lt;label for="card"&gt;
                &lt;span&gt;Card type:&lt;/span&gt;
                &lt;select id="card" name="usercard"&gt;
                    &lt;option value="visa"&gt;Visa&lt;/option&gt;
                    &lt;option value="mc"&gt;Mastercard&lt;/option&gt;
                    &lt;option value="amex"&gt;American Express&lt;/option&gt;
                &lt;/select&gt;
            &lt;/label&gt;
        &lt;/p&gt;
        &lt;p&gt;
            &lt;label for="number"&gt;
                &lt;span&gt;Card number:&lt;/span&gt;
                &lt;input type="text" id="number" name="cardnumber" required /&gt;
                &lt;strong&gt;&lt;abbr title="required"&gt;*&lt;/abbr&gt;&lt;/strong&gt;
            &lt;/label&gt;
        &lt;/p&gt;
        &lt;p&gt;
            &lt;label for="date"&gt;
                &lt;span&gt;Expiration date:&lt;/span&gt;
                &lt;input type="text" id="date" name="expiration" required /&gt;
                &lt;strong&gt;&lt;abbr title="required"&gt;*&lt;/abbr&gt;&lt;/strong&gt;
                &lt;em&gt;formated as mm/yy&lt;/em&gt;
            &lt;/label&gt;
        &lt;/p&gt;
    &lt;/section&gt;
    
    &lt;section&gt;
        &lt;p&gt;
            &lt;button&gt;Validate the payment&lt;/button&gt;
        &lt;/p&gt;
    &lt;/section&gt;
&lt;/form&gt;</pre>
<p>See this form in action: [Add a link to the form]</p>
<h2 id="HTML_widgets">HTML widgets</h2>
<p>When you build a form, you need to use some widgets to collect the data from the user. In this article we will see how to display those widgets, if you want to know more about the way those widgets work, it is detailed in the article: <a href="/en-US/docs/HTML/Forms/The_native_form_widgets" title="/en-US/docs/HTML/Forms/The_native_form_widgets">The native form widgets</a>.</p>
<h3 id="The_.7B.7BHTMLElement(.22input.22).7D.7D_element">The {{HTMLElement("input")}} element</h3>
<p>This element is kind of special, it can be almost everything. By simply setting it's <code>type</code> attribute, it can change radically. To make things a little simpler, the value for the <code>type</code> attribute can be categorize in four kind of rendering: single line text fields, controls without text input, time and date controls and buttons. Because of this polymorphism, the {{HTMLElement("input")}} element support many attributes but it is difficult to know which are relevant and which are required. It all depends on the value of the type attribute.</p>
<p>This is all summarized in the following table (for a full list of all attributes, visit the page for the {{HTMLElement("input")}} element) :</p>
<table>
  <thead>
    <tr>
      <th scope="col">Value of the type attribute</th>
      <th scope="col">Description</th>
      <th scope="col">Required attributes</th>
      <th scope="col">Relevant attributes</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th colspan="4" style="text-align: center;">Single line text fields</th>
    </tr>
    <tr>
      <td><code>text</code></td>
      <td>This is the most basic text field. the value <em>text</em> for the <code>type</code> attribute is the default value of this attribute.</td>
      <td>&nbsp;</td>
      <td>{{htmlattrxref("autocomplete","input")}}, {{htmlattrxref("list","input")}}, {{htmlattrxref("maxlength","input")}}, {{htmlattrxref("pattern","input")}}, {{htmlattrxref("placeholder","input")}}, {{htmlattrxref("readonly","input")}}, {{htmlattrxref("required","input")}}, {{htmlattrxref("size","input")}}, {{htmlattrxref("spellcheck","input")}}</td>
    </tr>
    <tr>
      <td><code>email</code></td>
      <td>A field for editing one or more e-mail addresses.</td>
      <td>&nbsp;</td>
      <td>{{htmlattrxref("autocomplete","input")}}, {{htmlattrxref("list","input")}}, {{htmlattrxref("maxlength","input")}}, {{htmlattrxref("multiple","input")}}, {{htmlattrxref("pattern","input")}}, {{htmlattrxref("placeholder","input")}}, {{htmlattrxref("readonly","input")}}, {{htmlattrxref("required","input")}}, {{htmlattrxref("size","input")}}</td>
    </tr>
    <tr>
      <td><code>password</code></td>
      <td>The value of this text field is obscured</td>
      <td>&nbsp;</td>
      <td>{{htmlattrxref("autocomplete","input")}}, {{htmlattrxref("list","input")}}, {{htmlattrxref("maxlength","input")}}, {{htmlattrxref("readonly","input")}}, {{htmlattrxref("required","input")}}, {{htmlattrxref("size","input")}}</td>
    </tr>
    <tr>
      <td><code>search</code></td>
      <td>A field for entering search strings</td>
      <td>&nbsp;</td>
      <td>{{htmlattrxref("autocomplete","input")}}, {{htmlattrxref("autosave","input")}}, {{htmlattrxref("list","input")}}, {{htmlattrxref("maxlength","input")}}, {{htmlattrxref("pattern","input")}}, {{htmlattrxref("placeholder","input")}}, {{htmlattrxref("readonly","input")}}, {{htmlattrxref("required","input")}}, {{htmlattrxref("size","input")}}, {{htmlattrxref("spellcheck","input")}}</td>
    </tr>
    <tr>
      <td><code>tel</code></td>
      <td>A field for editing a phone number.</td>
      <td>&nbsp;</td>
      <td>{{htmlattrxref("autocomplete","input")}}, {{htmlattrxref("list","input")}}, {{htmlattrxref("maxlength","input")}}, {{htmlattrxref("pattern","input")}}, {{htmlattrxref("placeholder","input")}}, {{htmlattrxref("readonly","input")}}, {{htmlattrxref("required","input")}}, {{htmlattrxref("size","input")}}</td>
    </tr>
    <tr>
      <td><code>url</code></td>
      <td>A field for editing an absolute URL.</td>
      <td>&nbsp;</td>
      <td>{{htmlattrxref("autocomplete","input")}}, {{htmlattrxref("list","input")}}, {{htmlattrxref("maxlength","input")}}, {{htmlattrxref("pattern","input")}}, {{htmlattrxref("placeholder","input")}}, {{htmlattrxref("readonly","input")}}, {{htmlattrxref("required","input")}}, {{htmlattrxref("size","input")}}</td>
    </tr>
    <tr>
      <th colspan="4" style="text-align: center;">Controls without text input</th>
    </tr>
    <tr>
      <td><code>checkbox</code></td>
      <td>Display a checkbox</td>
      <td>&nbsp;</td>
      <td>{{htmlattrxref("checked","input")}}, {{htmlattrxref("required","input")}}</td>
    </tr>
    <tr>
      <td><code>color</code></td>
      <td>A control to specify a color</td>
      <td>&nbsp;</td>
      <td>{{htmlattrxref("autocomplete","input")}}, {{htmlattrxref("list","input")}}, {{htmlattrxref("required","input")}}</td>
    </tr>
    <tr>
      <td><code>file</code></td>
      <td>A control that lets the user select a file.</td>
      <td>&nbsp;</td>
      <td>{{htmlattrxref("accept","input")}}, {{htmlattrxref("multiple","input")}}, {{htmlattrxref("required","input")}}</td>
    </tr>
    <tr>
      <td><code>hidden</code></td>
      <td>A control that is not displayed, but whose value is submitted to the server.</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
    </tr>
    <tr>
      <td><code>number</code></td>
      <td>A control for entering a floating point number.</td>
      <td>&nbsp;</td>
      <td>{{htmlattrxref("autocomplete","input")}}, {{htmlattrxref("list","input")}}, {{htmlattrxref("max","input")}}, {{htmlattrxref("min","input")}}, {{htmlattrxref("readonly","input")}}, {{htmlattrxref("required","input")}}, {{htmlattrxref("step","input")}}</td>
    </tr>
    <tr>
      <td><code>radio</code></td>
      <td>Display a radio button</td>
      <td>&nbsp;</td>
      <td>{{htmlattrxref("checked","input")}}, {{htmlattrxref("required","input")}}</td>
    </tr>
    <tr>
      <td><code>range</code></td>
      <td>A control for entering a number whose exact value is not important.</td>
      <td>&nbsp;</td>
      <td>{{htmlattrxref("autocomplete","input")}}, {{htmlattrxref("list","input")}}, {{htmlattrxref("max","input")}}, {{htmlattrxref("min","input")}}, {{htmlattrxref("required","input")}}, {{htmlattrxref("step","input")}}</td>
    </tr>
    <tr>
      <th colspan="4" style="text-align: center;">Time and date controls</th>
    </tr>
    <tr>
      <td><code>date</code></td>
      <td>A control for entering a date (year, month, and day, with no time).</td>
      <td>&nbsp;</td>
      <td>{{htmlattrxref("autocomplete","input")}}, {{htmlattrxref("list","input")}}, {{htmlattrxref("max","input")}}, {{htmlattrxref("min","input")}}, {{htmlattrxref("readonly","input")}}, {{htmlattrxref("required","input")}}</td>
    </tr>
    <tr>
      <td><code>datetime</code></td>
      <td>A control for entering a date and time (hour, minute, second, and fraction of a second) based on UTC time zone.</td>
      <td>&nbsp;</td>
      <td>{{htmlattrxref("autocomplete","input")}}, {{htmlattrxref("list","input")}}, {{htmlattrxref("max","input")}}, {{htmlattrxref("min","input")}}, {{htmlattrxref("readonly","input")}}, {{htmlattrxref("required","input")}}</td>
    </tr>
    <tr>
      <td><code>datetime-local</code></td>
      <td>A control for entering a date and time, with no time zone.</td>
      <td>&nbsp;</td>
      <td>{{htmlattrxref("autocomplete","input")}}, {{htmlattrxref("list","input")}}, {{htmlattrxref("max","input")}}, {{htmlattrxref("min","input")}}, {{htmlattrxref("readonly","input")}}, {{htmlattrxref("required","input")}}</td>
    </tr>
    <tr>
      <td><code>month</code></td>
      <td>A control for entering a month and year, with no time zone.</td>
      <td>&nbsp;</td>
      <td>{{htmlattrxref("autocomplete","input")}}, {{htmlattrxref("list","input")}}, {{htmlattrxref("max","input")}}, {{htmlattrxref("min","input")}}, {{htmlattrxref("readonly","input")}}, {{htmlattrxref("required","input")}}</td>
    </tr>
    <tr>
      <td><code>time</code></td>
      <td>A control for entering a time value with no time zone.</td>
      <td>&nbsp;</td>
      <td>{{htmlattrxref("autocomplete","input")}}, {{htmlattrxref("list","input")}}, {{htmlattrxref("max","input")}}, {{htmlattrxref("min","input")}}, {{htmlattrxref("readonly","input")}}, {{htmlattrxref("required","input")}}</td>
    </tr>
    <tr>
      <td><code>week</code></td>
      <td>A control for entering a date consisting of a week-year number and a week number with no time zone.</td>
      <td>&nbsp;</td>
      <td>{{htmlattrxref("autocomplete","input")}}, {{htmlattrxref("list","input")}}, {{htmlattrxref("max","input")}}, {{htmlattrxref("min","input")}}, {{htmlattrxref("readonly","input")}}, {{htmlattrxref("required","input")}}</td>
    </tr>
    <tr>
      <th colspan="4" style="text-align: center;">Buttons</th>
    </tr>
    <tr>
      <td><code>button</code></td>
      <td>A push button with no default behavior.</td>
      <td>&nbsp;</td>
      <td>{{htmlattrxref("formaction","input")}}, {{htmlattrxref("formenctype","input")}}, {{htmlattrxref("formmethod","input")}}, {{htmlattrxref("formnovalidate","input")}}, {{htmlattrxref("formtarget","input")}}</td>
    </tr>
    <tr>
      <td><code>image</code></td>
      <td>A graphical submit button.</td>
      <td>{{htmlattrxref("src","input")}}, {{htmlattrxref("alt","input")}}</td>
      <td>{{htmlattrxref("width","input")}}, {{htmlattrxref("height","input")}}, {{htmlattrxref("formaction","input")}}, {{htmlattrxref("formenctype","input")}}, {{htmlattrxref("formmethod","input")}}, {{htmlattrxref("formnovalidate","input")}}, {{htmlattrxref("formtarget","input")}}</td>
    </tr>
    <tr>
      <td><code>reset</code></td>
      <td>A button that resets the contents of the form to default values.</td>
      <td>&nbsp;</td>
      <td>{{htmlattrxref("formaction","input")}}, {{htmlattrxref("formenctype","input")}}, {{htmlattrxref("formmethod","input")}}, {{htmlattrxref("formnovalidate","input")}}, {{htmlattrxref("formtarget","input")}}</td>
    </tr>
    <tr>
      <td><code>submit</code></td>
      <td>A button that submits the form.</td>
      <td>&nbsp;</td>
      <td>{{htmlattrxref("formaction","input")}}, {{htmlattrxref("formenctype","input")}}, {{htmlattrxref("formmethod","input")}}, {{htmlattrxref("formnovalidate","input")}}, {{htmlattrxref("formtarget","input")}}</td>
    </tr>
  </tbody>
</table>
<p>If for some reason, the value set in the type attribute is not supported by a browser, it render the {{HTMLElement("input")}} element as if the value was <em>text</em>.</p>
<p>Even if the {{HTMLElement("input")}} element is a powerful tool, it can not do everything and there is a few other elements to handled those cases.</p>
<h3 id="The_.7B.7BHTMLElement(.22textarea.22).7D.7D_element">The {{HTMLElement("textarea")}} element</h3>
<p>This element is dedicated to the multiline text field. It works exactly as a single line text field except that it allows line break in the text typed by the user. It also accept a few extra attributes to control it's rendering on several lines:</p>
<table>
  <caption>
    Attributes for the {{HTMLElement("textarea")}} element</caption>
  <thead>
    <tr>
      <th scope="col">Attribute&nbsp;name</th>
      <th scope="col">Default&nbsp;value</th>
      <th scope="col">Description</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>{{htmlattrxref("cols","textarea")}}</td>
      <td><code>20</code></td>
      <td>The visible width of the text control, in average character widths.</td>
    </tr>
    <tr>
      <td>{{htmlattrxref("rows","textarea")}}</td>
      <td>&nbsp;</td>
      <td>The number of visible text lines for the control.</td>
    </tr>
    <tr>
      <td>{{htmlattrxref("wrap","textarea")}}</td>
      <td><code>soft</code></td>
      <td>Indicates how the control wraps text. Possible values are: <code>hard</code> or <code>soft</code></td>
    </tr>
  </tbody>
</table>
<p>Note that the {{HTMLElement("textarea")}} element work a little bit differently than the {{HTMLElement("input")}} element. The {{HTMLElement("input")}} element is a self closing element, which means that it can not contain any child elements. On the contrary, the {{HTMLElement("textarea")}} element is a regular element that can contain text content children.</p>
<p>This has two impact:</p>
<ul>
  <li>&nbsp;If you want to define a default value for an {{HTMLElement("input")}} element, you have to use the <code>value</code> attribute, but if you want to define a default value for a {{HTMLElement("textarea")}} element, you have to write this value between the starting tag and the closing tag of the element</li>
  <li>Because of its nature the {{HTMLElement("textarea")}} element only accept text content which means that any HTML content put inside a {{HTMLElement("textarea")}} element is rendered as if it was plain text content.</li>
</ul>
<p>In the following example, the {{HTMLElement("textarea")}} elements will be rendered exactly the same:</p>
<pre class="brush:html;">
&lt;form&gt;
    &lt;p&gt;
        &lt;label for="text_1"&gt;With regular HTML&lt;/label&gt;&lt;br&gt;
        &lt;textarea id="text_1" name="regular"&gt;&lt;p&gt;I'm a paragraphe&lt;/p&gt;&lt;/textarea&gt;
    &lt;/p&gt;
    &lt;p&gt;
        &lt;label for="text_2"&gt;With escaped HTML&lt;/label&gt;&lt;br&gt;
        &lt;textarea id="text_2" name="escaped"&gt;&amp;lt;p&amp;gt;I'm a paragraphe&amp;lt;/p&amp;gt;&lt;/textarea&gt;
    &lt;/p&gt;
    &lt;p&gt;
        &lt;button&gt;Send me&lt;/button&gt;
    &lt;/p&gt;
&lt;/form&gt;</pre>
<h3 id="The_.7B.7BHTMLElement(.22select.22).7D.7D.2C_.7B.7BHTMLElement(.22option.22).7D.7D_and_.7B.7BHTMLElement(.22optgroup.22).7D.7D_elements">The {{HTMLElement("select")}}, {{HTMLElement("option")}} and {{HTMLElement("optgroup")}} elements</h3>
<p>The {{HTMLElement("select")}} element is especially made to build select boxes (sometimes also known as combo boxes). A select box is a widget that allow a user to choose one or more predefine values. The difference between a single value select box and a multiple value select box will be detailed in the article: The native form widget.</p>
<p>Each value inside the select box is define with an {{HTMLElement("option")}} element and those elements can be grouped inside {{HTMLElement("option")}} elements.</p>
<p>Let's take an example:</p>
<pre class="brush:html;">
&lt;form&gt;
    &lt;p&gt;
        &lt;label for="myFruit"&gt;Pick a fruit&lt;/label&gt;
        &lt;select id="muFruit" name="fruit"&gt;
            &lt;!-- There is a trick here you think you'll pick 
                 a banana but you'll eat an Orange &gt;:-) --&gt;
            &lt;option value="orange"&gt;Banana&lt;/option&gt;
            &lt;option&gt;Cherry&lt;/option&gt;
            &lt;optgroup label="berries"&gt;
                &lt;option&gt;Blueberry&lt;/option&gt;
                &lt;option&gt;Raspberry&lt;/option&gt;
                &lt;option&gt;Strawberry&lt;/option&gt;
            &lt;/optgroup&gt;
        &lt;/select&gt;
    &lt;/p&gt;
&lt;/form&gt;</pre>
<p>If an {{HTMLElement("option")}} element is set with a <code>value</code> attribute, it's the value of this attribute which is sent. If the <code>value</code> attribute is omitted, it's the content of the {{HTMLElement("option")}} element that is sent as the value for the select box.</p>
<p>On the {{HTMLElement("optgroup")}} element, the <code>label</code> attribute will be display before the values, but even if it looks more or less like an option, it is not selectable.</p>
<table>
  <caption>
    Attributes for the {{HTMLElement("option")}} element</caption>
  <thead>
    <tr>
      <th scope="col">Attribute&nbsp;name</th>
      <th scope="col">Default&nbsp;value</th>
      <th scope="col">Description</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>{{htmlattrxref("label","option")}}</td>
      <td>&nbsp;</td>
      <td>This attribute is text for the label indicating the meaning of the option. If the <code>label</code> attribute isn't defined, its value is that of the element text content.</td>
    </tr>
    <tr>
      <td>{{htmlattrxref("selected","option")}}</td>
      <td>(<em>false</em>)</td>
      <td>If present, this Boolean attribute indicates that the option is initially selected.</td>
    </tr>
  </tbody>
</table>
<table>
  <caption>
    Attributes for the {{HTMLElement("optgroup")}} element</caption>
  <thead>
    <tr>
      <th scope="col">Attribute&nbsp;name</th>
      <th scope="col">Default&nbsp;value</th>
      <th scope="col">Description</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>{{htmlattrxref("label","optgroup")}}</td>
      <td>&nbsp;</td>
      <td>The name of the group of options. This attribute is mandatory.</td>
    </tr>
  </tbody>
</table>
<h3 id="The_.7B.7BHTMLElement(.22datalist.22).7D.7D_element">The {{HTMLElement("datalist")}} element</h3>
<p>This&nbsp; element extend the existing widgets by providing some preset value for a&nbsp; given widgets. The most know use case for this is an autocompletion&nbsp; list for text fields. The values available are set with {{HTMLElement("option")}} elements within the {{HTMLElement("datalist")}} element.</p>
<p>To bind a widget with a {{HTMLElement("datalist")}} element you have to use the <code>list</code> attribute on the target widget. The <code>list</code> attribute is referencing the value of the <code>id</code> attribute of the {{HTMLElement("datalist")}} element to use.</p>
<p>The&nbsp; {{HTMLElement("datalist")}} element is a very new addition to HTML forms so there is still some browser that do not support it. To handle this, here is a little trick to have a nice fallback for those browsers:</p>
<pre class="brush:html;">
&lt;form&gt;
    &lt;p&gt;
        &lt;label for="myFruit"&gt;What is your favorite fruit?&lt;/label&gt;
        &lt;input type="text" id="myFruit" name="fruit" list="fruitList" /&gt;
        
        &lt;datalist id="fruitList"&gt;
            &lt;label for="suggestion"&gt;or pick a fruit&lt;/label&gt;
            &lt;select id="suggestion" name="altFruit"&gt;
                &lt;option value="banana"&gt;Banana&lt;/option&gt;
                &lt;option value="cherry"&gt;Cherry&lt;/option&gt;
                &lt;option value="strawberry"&gt;Strawberry&lt;/option&gt;
            &lt;/select&gt;
        &lt;/datalist&gt;
    &lt;/p&gt;
&lt;/form&gt;</pre>
<p>On the one hand, browsers that support the {{HTMLElement("datalist")}} element will ignore all the elements that are not {{HTMLElement("option")}} element and will work as expected. On the other hand, browsers that do not support the {{HTMLElement("datalist")}} element will display the label and the select box. Of course, there is other way to handle the lack of support for the {{HTMLElement("datalist")}} element but it require the use of JavaScript which is not necessarily always reliable.</p>
<p>[Add a screenshot of this example]</p>
<h3 id="The_.7B.7BHTMLElement(.22meter.22).7D.7D_and_.7B.7BHTMLElement(.22progress.22).7D.7D_elements">The {{HTMLElement("meter")}} and {{HTMLElement("progress")}} elements</h3>
<p>Those two elements are a way to graphically represent a given numeric value. The difference between the two elements is mainly semantic:</p>
<ul>
  <li>The {{HTMLElement("meter")}} element represent a static value and its relative position between a min and a max value</li>
  <li>The {{HTMLElement("progress")}} element represent a changing value that evolved between a min value and a max value. It worth noting that animating the change of value have to be down with JavaScript. The element itself does not have any mechanism to do it on its own.</li>
</ul>
<p>Du to their nature those element support a set of specific attributes:</p>
<table>
  <caption>
    Attributes for the {{HTMLElement("meter")}} element</caption>
  <thead>
    <tr>
      <th scope="col">Attribute&nbsp;name</th>
      <th scope="col">Default&nbsp;value</th>
      <th scope="col">Description</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>{{htmlattrxref("min","meter")}}</td>
      <td>0</td>
      <td>The lower numeric bound of the measured range.</td>
    </tr>
    <tr>
      <td>{{htmlattrxref("max","meter")}}</td>
      <td>1</td>
      <td>The upper numeric bound of the measured range.</td>
    </tr>
    <tr>
      <td>{{htmlattrxref("low","meter")}}</td>
      <td>the <code>min</code> value</td>
      <td>The upper numeric bound of the low end of the measured range.</td>
    </tr>
    <tr>
      <td>{{htmlattrxref("high","meter")}}</td>
      <td>the <code>max</code> value</td>
      <td>The lower numeric bound of the high end of the measured range.</td>
    </tr>
    <tr>
      <td>{{htmlattrxref("optimum","meter")}}</td>
      <td>&nbsp;</td>
      <td>The optimal numeric value.</td>
    </tr>
  </tbody>
</table>
<table>
  <caption>
    Attributes for the {{HTMLElement("progress")}} element</caption>
  <thead>
    <tr>
      <th scope="col">Attribute&nbsp;name</th>
      <th scope="col">Default&nbsp;value</th>
      <th scope="col">Description</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>{{htmlattrxref("max","progress")}}</td>
      <td>&nbsp;</td>
      <td>This attribute describes how much work the task indicated by the {{HTMLElement("progress")}} element requires.</td>
    </tr>
  </tbody>
</table>
<h3 id="The_.7B.7BHTMLElement(.22button.22).7D.7D_element">The {{HTMLElement("button")}} element</h3>
<p>A {{HTMLElement("button")}} element is the easiest way to create a form button. A button can be of three type defined by the value of the type attribute:</p>
<ul>
  <li>A submit button: it sends the form's data to the web page defined by the action attribute of the &lt;form&gt; element.</li>
  <li>A reset button: it resets all the form widgets to their default value immediately. From a UX point of view it is considered bad practice to use such a button.</li>
  <li>An anonymous button: This kind of button just do nothing. It is used with Javascript to build custom buttons.</li>
</ul>
<table>
  <caption>
    Attributes for the {{HTMLElement("button")}} element</caption>
  <thead>
    <tr>
      <th scope="col">Attribute&nbsp;name</th>
      <th scope="col">Default&nbsp;value</th>
      <th scope="col">Description</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>{{htmlattrxref("type","button")}}</td>
      <td><code>submit</code></td>
      <td>The type of the button. Possible values are: <code>button</code>, <code>reset</code> or <code>submit</code></td>
    </tr>
    <tr>
      <td>{{htmlattrxref("formaction","button")}}</td>
      <td>&nbsp;</td>
      <td>If the button is a submit button, the value of this attribute overrides the value of the <code>action</code> attribute on the {{HTMLElement("form")}} element.</td>
    </tr>
    <tr>
      <td>{{htmlattrxref("formenctype","button")}}</td>
      <td>&nbsp;</td>
      <td>If the button is a submit button, the value of this attribute overrides the value of the <code>enctype</code> attribute on the {{HTMLElement("form")}} element.</td>
    </tr>
    <tr>
      <td>{{htmlattrxref("formmethod","button")}}</td>
      <td>&nbsp;</td>
      <td>If the button is a submit button, the value of this attribute overrides the value of the <code>method</code> attribute on the {{HTMLElement("form")}} element.</td>
    </tr>
    <tr>
      <td>{{htmlattrxref("formnovalidate","button")}}</td>
      <td>&nbsp;</td>
      <td>If the button is a submit button, the value of this attribute overrides the value of the <code>novalidate</code> attribute on the {{HTMLElement("form")}} element.</td>
    </tr>
    <tr>
      <td>{{htmlattrxref("formtarget","button")}}</td>
      <td>&nbsp;</td>
      <td>If the button is a submit button, the value of this attribute overrides the value of the <code>target</code> attribute on the {{HTMLElement("form")}} element.</td>
    </tr>
  </tbody>
</table>
<p>Technically speaking, there is almost no difference between a button define with the {{HTMLElement("button")}} element or the {{HTMLElement("input")}} element. The only noticeable difference is the label of the button itself. Within an {{HTMLElement("input")}} element, the label can only be character data, on the contrary, within a {{HTMLElement("button")}} element, the label can be plain HTML which means it can be styled accordingly.</p>
<div class="note">
  For historical reason the {{HTMLElement("button")}} element was no used really often and in many form, developers prefer to use the button made with the {{HTMLElement("input")}} element. This is due to a bug in legacy version of Internet Explorer (IE). In IE6 and IE7, if you add a <code>name</code> and a <code>value</code> attribute to a {{HTMLElement("button")}} element, they do not send the content of the <code>value</code> attribute but the raw content of the button instead. This has been fixed since IE8 so there is currently no reason to avoid using the {{HTMLElement("button")}} element.</div>
<h3 id="Common_attributes">Common attributes</h3>
<p>The elements used to define form widgets can have some specific attributes. However, there is a set of common attributes to all this elements that allow you to have some control over those widgets. Here is a list of those attributes:</p>
<table>
  <thead>
    <tr>
      <th scope="col">Attribute&nbsp;name</th>
      <th scope="col">Default&nbsp;value</th>
      <th scope="col">Description</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code>autofocus</code></td>
      <td>(<em>false</em>)</td>
      <td>This Boolean attribute lets you specify that the element should have input focus when the page loads, unless the user overrides it, for example by typing in a different control. Only one form-associated element in a document can have this attribute specified.</td>
    </tr>
    <tr>
      <td><code>disabled</code></td>
      <td>(<em>false</em>)</td>
      <td>This Boolean attribute indicates that the user cannot interact with the element. If this attribute is not specified, the element inherits its setting from the containing element, for example {{HTMLElement("fieldset")}}; if there is no containing element with the <code>disabled</code> attribute set, then the element is enabled.</td>
    </tr>
    <tr>
      <td><code>form</code></td>
      <td>&nbsp;</td>
      <td>The form element that the button is associated with. The value of the attribute must be the <code>id</code> attribute of a {{HTMLElement("form")}} element in the same document. In theory, it allow to set a form widget outside of a {{HTMLElement("form")}} element. In practice there is no browser which support that feature.</td>
    </tr>
    <tr>
      <td><code>name</code></td>
      <td>&nbsp;</td>
      <td>The name of the element, which is submitted with the form data.</td>
    </tr>
    <tr>
      <td><code>value</code></td>
      <td>&nbsp;</td>
      <td>The initial value of the element.</td>
    </tr>
  </tbody>
</table>
<h2 id="Using_ARIA_to_structure_HTML_forms">Using <a href="/en-US/docs/Accessibility/ARIA" title="/en-US/docs/Accessibility/ARIA">ARIA</a> to structure HTML forms</h2>
<p><a href="/en-US/docs/Accessibility/ARIA" title="/en-US/docs/Accessibility/ARIA">ARIA</a> is <a href="http://www.w3.org/TR/wai-aria/" rel="external" title="http://www.w3.org/TR/wai-aria/">a W3C Candidate Recommendation</a> which is an addition to HTML to improve the accessibility of rich Internet application. ARIA can be used in many cases beyond HTML form. We will discuss its use in more detail in the "How to build custom form widgets" article, but there is some basics that are good to know.</p>
<p>Before going further, it worth noting that the support of ARIA among browsers and assistive technologies is far from perfect, but it's improving. Just to understand the issue, when a browser encounter an ARIA attribute, it have to send information to the OS accessibility layer. Not all browser are good at doing this cross platform. The assistive technologies, on their own, have to connect themselves to the OS accessibility layer to handle the information that come from the browsers. Surprisingly, not all assistive technologies do it well. So using ARIA does not mean that your web application will be accessible, but it means that you do your best to achieve this. Unfortunately, for the time being, ARIA remain a best effort technology but it's always better than nothing.</p>
<p>If you want to dig into using ARIA with HTML forms, feel free to <a href="/en-US/docs/Accessibility/ARIA/forms" title="/en-US/docs/Accessibility/ARIA/forms">read the related section in the ARIA documentation</a>.</p>
<h3 id="The_aria-labelledby_attribute">The <a href="/en-US/docs/Accessibility/ARIA/ARIA_Techniques/Using_the_aria-labelledby_attribute" title="/en-US/docs/Accessibility/ARIA/ARIA_Techniques/Using_the_aria-labelledby_attribute"><code>aria-labelledby</code></a> attribute</h3>
<p>This attribute is a convenient way to define a label without using the {{HTMLElement("label")}} element. The attribute is set on the widget element and reference the <code>id</code> attribute of the element to use as a label.</p>
<pre class="brush:html;">
&lt;form&gt;
    &lt;p id="fruitLabel"&gt;What's your favorite fruit&lt;/p&gt;
    &lt;p&gt;
        &lt;input type="text" name="fruit" aria-labelledby="fruitLabel"&gt;
    &lt;/p&gt;
&lt;/form&gt;</pre>
<p>Conceptually it's the opposite of the <code>for</code> attribute on the {{HTMLElement("label")}} element. With the for attribute, you reference the <code>id</code> of the widget but with the <code>aria-labbeldby</code> attribute, you reference the <code>id</code> of the label.</p>
<h3 id="The_aria-describedby_attribute">The <a href="/en-US/docs/Accessibility/ARIA/ARIA_Techniques/Using_the_aria-describedby_attribute" title="/en-US/docs/Accessibility/ARIA/ARIA_Techniques/Using_the_aria-describedby_attribute"><code>aria-describedby</code></a> attribute</h3>
<p>This attribute works like the <code>aria-labelledby</code> attribute. The difference is mainly semantic. A label define the essence of an object, while a description provides more information that the user might need.</p>
<h3 id="The_aria-label_attribute">The <a href="/en-US/docs/Accessibility/ARIA/ARIA_Techniques/Using_the_aria-label_attribute" title="/en-US/docs/Accessibility/ARIA/ARIA_Techniques/Using_the_aria-label_attribute"><code>aria-label</code></a> attribute</h3>
<p>This attribute is used when there is no explicit label in the DOM for a given widget. It allow to give a widget that will be passed to assitive technologies but without the need to create a DOM node for this.</p>
<pre class="brush:html;">
&lt;form&gt;
    &lt;p&gt;
        &lt;input type="search" name="q" aria-label="Search" /&gt;
        &lt;input type="submit" value="Go" /&gt;
    &lt;/p&gt;
&lt;/form&gt;</pre>
<h3 id="The_role_attribute">The <a href="/en-US/docs/Accessibility/ARIA/ARIA_Techniques" title="/en-US/docs/Accessibility/ARIA/ARIA_Techniques"><code>role</code></a> attribute</h3>
<p>This is the most important ARIA attribute. It allow to give specific semantic understandable by assitive technologies to a given HTML element. There is many roles available and some of them are dedicated to form widgets.</p>
<p>ARIA try to provide a specific semantic for widget that are currently not existing in HTML as well as for existing ones. We will see in detail how to use those roles in the article: How to build custom form widgets.</p>
<p>Those roles for form widgets are :</p>
<ul>
  <li><a href="/en-US/docs/Accessibility/ARIA/ARIA_Techniques/Using_the_button_role" title="/en-US/docs/Accessibility/ARIA/ARIA_Techniques/Using_the_button_role">Button</a></li>
  <li><a href="/en-US/docs/Accessibility/ARIA/ARIA_Techniques/Using_the_checkbox_role" title="/en-US/docs/Accessibility/ARIA/ARIA_Techniques/Using_the_checkbox_role">Checkbox</a></li>
  <li><a href="/en-US/docs/Accessibility/ARIA/ARIA_Techniques/Using_the_progressbar_role" title="/en-US/docs/Accessibility/ARIA/ARIA_Techniques/Using_the_progressbar_role">Progressbar</a></li>
  <li>Radio</li>
  <li><a href="/en-US/docs/Accessibility/ARIA/ARIA_Techniques/Using_the_slider_role" title="/en-US/docs/Accessibility/ARIA/ARIA_Techniques/Using_the_slider_role">Slider</a></li>
  <li>Spinbutton</li>
  <li><a href="/en-US/docs/Accessibility/ARIA/ARIA_Techniques/Using_the_textbox_role" title="/en-US/docs/Accessibility/ARIA/ARIA_Techniques/Using_the_textbox_role">textbox</a></li>
</ul>
<p>It's also worth noting that it existing what is called composite role :</p>
<ul>
  <li><a href="/en-US/docs/Accessibility/ARIA/ARIA_Techniques/Using_the_listbox_role" title="/en-US/docs/Accessibility/ARIA/ARIA_Techniques/Using_the_listbox_role">Listbox</a></li>
  <li>Radiogroup</li>
</ul>
<p>If those roles are extremely useful, know that <a href="/en-US/docs/Accessibility/ARIA/ARIA_Techniques" title="/en-US/docs/Accessibility/ARIA/ARIA_Techniques">there is more</a>, ARIA is a very large specification and to dig into it can help you in many way beyond HTML forms.</p>
<h2 id="Conclusion">Conclusion</h2>
<p>You now have all the knowledge to properly structure your HTML Forms, the next article will dig into implementation detail and functional expectation: The native form widgets<br />
  &nbsp;</p>
Revert to this revision