HTML Form Element
Every form you have ever filled in, from a one-box search bar to a long visa application, begins with the same element: <form>. It looks small, but it has an important job. It marks the boundary of the conversation: "everything in here belongs together, and when the visitor submits, send all of it, to this place, in this way."
If the fields are the questions on a paper form, the <form> element is the envelope: it holds the answers, carries an address, and decides how the package travels. In this lesson, you will learn how it works, what its attributes do, and how browsers turn what visitors type into something a server can read.
What You Will Learnβ
- What the
<form>element is, and what it does - How a browser turns fields into name and value pairs
- The main form attributes:
action,method,enctype,target,autocomplete, andnovalidate - Three ways a form gets submitted
- How to build search, login, and newsletter forms
- How the
formattribute connects fields outside a form - Accessibility basics, and common mistakes
The Basicsβ
A form is a container. Fields go inside it, and a button submits it.
- HTML Code
- Browser Output
<form action="/search" method="get">
<label for="q">Search lessons</label>
<input type="search" id="q" name="q" />
<button type="submit">Search</button>
</form>
Here is what each part does:
| Part | Role |
|---|---|
<form> | The container |
action="/search" | Where to send the data: the address of the server program |
method="get" | How to send it: in the web address |
<input ... name="q"> | A field. name is the key it is sent under |
<button type="submit"> | Triggers the submission |
If someone types "tables" and presses Search, the browser goes to:
/search?q=tables
That q=tables is a name and value pair: the field's name, an equals sign, and what the visitor typed.
<form> does not save data, send an email, or log anyone in. It only packages and sends. A program on a server, written in a language such as Node.js, Python, PHP, or Java, receives the data and does the work.
How a Browser Builds the Dataβ
When a form is submitted, the browser visits every field inside it, and collects those that qualify. For each one, it creates a name and value pair. Then it joins all the pairs together.
| A field is included only when it... |
|---|
Has a name attribute that is not empty |
| Is not disabled |
| Is a checkbox or radio button that is checked (unchecked ones are skipped) |
Is a <select> with a selected option |
| Is not a button, unless that button was the one pressed |
Try it. Change the values, press Submit, and look at what would be sent. Notice that the third field has no name, so it is silently left out.
What the browser would send: (press Submit)
The result looks like name=Ada&topic=html. Pairs are joined with &, and special characters, such as spaces, are encoded (a space becomes + or %20). The browser does this for you.
A field with id but no name looks perfect on screen, but its value is never sent. If your server never receives a value, check the name first.
The Form Attributesβ
The <form> element has several attributes. Each gets its own lesson later, but here is the full map.
| Attribute | What it does | Common values | Lesson |
|---|---|---|---|
action | The URL that receives the data | /subscribe, https://... | Form Action |
method | How the data is sent | get, post, dialog | Form Methods |
enctype | How the data is encoded (for post) | application/x-www-form-urlencoded, multipart/form-data, text/plain | Multipart Form Data |
target | Where to show the response | _self, _blank | This lesson |
autocomplete | Lets the browser fill in fields | on, off | Autocomplete |
novalidate | Turns off the browser's built-in checks | (boolean) | Form Validation |
name | A name for the form, for scripts | signup | This lesson |
accept-charset | Which character encodings are accepted | UTF-8 | Rarely needed |
rel | Relationship hints for the target, such as noopener | noopener | This lesson |
action and method in One Lookβ
<form action="/subscribe" method="post">
...
</form>
action: if you leave it out, the form submits to the current page's own address.method: defaults togetif you leave it out. Usepostfor anything that changes data or is private.
You will study both in detail in the next two lessons.
target: Where the Reply Appearsβ
By default, the response replaces the current page. target can change that.
| Value | Result |
|---|---|
_self (default) | The same tab |
_blank | A new tab |
<form action="/print-preview" method="post" target="_blank" rel="noopener">
...
</form>
Opening forms in a new tab is unusual, and can surprise people. Do it only when there is a good reason.
autocompleteβ
Controls whether the browser may fill in saved values.
<form action="/login" method="post" autocomplete="on">
For most forms, the default is best. You will learn when and how to adjust it in Autocomplete.
novalidateβ
Browsers check fields such as required and type="email" before submitting. novalidate switches that off for the whole form, which is useful when you run your own validation script.
<form action="/signup" method="post" novalidate>
Without good custom checks, removing the browser's help makes your form worse. Do not use it unless you replace what it does. (In MDX or React, this attribute is spelled noValidate.)
Three Ways to Submit a Formβ
- Press a submit button:
<button type="submit">or<input type="submit">. - Press Enter while typing in most single-line fields. The browser acts as if the first submit button were pressed.
- Submit from JavaScript:
form.requestSubmit()(which runs validation) orform.submit()(which does not).
<form action="/subscribe" method="post">
<input type="email" name="email" />
<button type="submit">Subscribe</button> <!-- 1 -->
</form> <!-- pressing Enter in the input also submits (2) -->
Resetβ
A <button type="reset"> puts every field back to its starting value. Use it rarely. People sometimes press it by mistake and lose their work.
One Form, One Purposeβ
A page can have several forms, but each should have a single job: a search form in the header, a newsletter form in the footer, a comment form below an article.
| Rule | Why |
|---|---|
| Do not nest forms | A <form> inside another <form> is invalid, and browsers will ignore the inner one |
| One submit action per form | Mixing purposes confuses users and breaks data |
| Keep related fields together | Everything the server needs for one action goes in the same form |
- Invalid
- Valid
<form action="/signup" method="post">
<input type="email" name="email" />
<form action="/search" method="get"> <!-- not allowed -->
<input type="search" name="q" />
</form>
</form>
<form action="/search" method="get">
<input type="search" name="q" />
</form>
<form action="/signup" method="post">
<input type="email" name="email" />
</form>
What Can Go Inside a Form?β
Almost anything. Forms hold text, headings, paragraphs, lists, and layout elements, along with the controls.
<form action="/feedback" method="post">
<h2>Tell us what you think</h2>
<p>It takes one minute.</p>
<label for="msg">Your message</label>
<textarea id="msg" name="message"></textarea>
<button type="submit">Send</button>
</form>
The elements that actually take part in submission are called form controls: <input>, <textarea>, <select>, <button>, and a few others. Controls are covered in the lessons that follow.
Fields Outside the Form: The form Attributeβ
Usually, controls sit inside the <form>. But sometimes a design puts a button or field elsewhere on the page. The form attribute links it back, by the form's id.
- HTML Code
- Browser Output
<form id="subscribe" action="/subscribe" method="post">
<label for="mail">Email</label>
<input type="email" id="mail" name="email" />
</form>
<!-- far away on the page, but still part of the form -->
<button type="submit" form="subscribe">Subscribe</button>
Some other content on the page...
The button sits outside the <form> tags, but pressing it submits the form. This also lets one control belong to a form even when the HTML layout (such as a table row) makes nesting awkward.
Real-World Examplesβ
1. A Search Formβ
A search form is a navigation aid, so give it the search landmark. Search uses get, so the address can be bookmarked and shared.
<form action="/search" method="get" role="search">
<label for="site-search">Search the site</label>
<input type="search" id="site-search" name="q" />
<button type="submit">Search</button>
</form>
role="search" lets screen reader users jump straight to the search box. (Modern HTML also has a dedicated <search> element that wraps a search form. role="search" on the form works everywhere.)
2. A Newsletter Formβ
- HTML Code
- Browser Output
<form action="/subscribe" method="post">
<h3>Get weekly tips</h3>
<label for="news-email">Email address</label>
<input
type="email"
id="news-email"
name="email"
autocomplete="email"
required
/>
<button type="submit">Subscribe</button>
</form>
Press Subscribe with the field empty, or with something that is not an email, and your browser will block the submission and explain why.
3. A Login Formβ
<form action="/login" method="post">
<label for="user">Email or username</label>
<input type="text" id="user" name="username" autocomplete="username" required />
<label for="pass">Password</label>
<input type="password" id="pass" name="password" autocomplete="current-password" required />
<button type="submit">Log in</button>
</form>
methodNever send a password with method="get". It would appear in the address bar, browser history, and server logs. Always use post, and make sure the site runs over HTTPS.
Accessibility at a Glanceβ
- A form is not a landmark on its own. It only becomes a "form" landmark for screen readers when it has an accessible name (with
aria-labeloraria-labelledby). Name important forms, but there is no need to name every small one. - Search forms should use
role="search"(or the<search>element). - Use real submit buttons. A
<div>styled as a button will not submit with Enter and cannot be reached by keyboard. - Do not remove the Enter key behavior. Many people submit with Enter.
- Keep the order logical. Tab order follows the source order, so write the fields in the order people should fill them in.
- Tell people what happened. After submission, show a clear confirmation or error message. You will learn more in Accessible Forms.
<form action="/contact" method="post" aria-labelledby="contact-title">
<h2 id="contact-title">Contact us</h2>
...
</form>
Common Mistakes to Avoidβ
- Fields without a
name. Their values are never sent. - Forgetting the submit button, or using
type="button", which does not submit. - Nesting one form inside another.
- Using
method="get"for passwords or other private data. - Leaving out
actionand wondering why the page reloads in place. (It submits to itself.) - Putting a whole page in one
<form>just because it contains fields. Group by purpose. - Using
novalidatewithout adding your own checks. - Using
<div>or<span>as buttons. - Forgetting
enctype="multipart/form-data"when uploading files. - Relying on the browser alone to check data. The server must check it too.
Practice Timeβ
Try these in your editor:
- Build a one-field search form with
method="get", and look at the address after you submit. - Add a second field and see how the address changes.
- Remove the
namefrom one field and check that its value disappears. - Change the method to
post, and note that the address no longer shows the data. - Build a newsletter form with an email field and a submit button.
- Add
required, and press Submit with the field empty. - Add
role="search"to a search form. - Place a submit button outside the form, and link it with the
formattribute. - Add
novalidate, and see what changes. Then remove it. - Bonus: use your browser's developer tools (Network tab) to inspect what is sent when you submit a
postform.
Quick Recapβ
Click a question to check your answer.
1. What does the <form> element do?
It groups form controls, and defines where (action) and how (method) the data is sent when the form is submitted. It does not store or process the data itself.
2. Which attribute decides the key under which a field's value is sent?
name. A control with no name is not included in the submission.
3. What happens if you leave out action and method?
The form submits to the current page's address, using the default method get.
4. Name three ways a form can be submitted.
Pressing a submit button, pressing Enter in a field, and calling requestSubmit() (or submit()) from JavaScript.
5. Can you place a form inside another form?
No. Nested forms are invalid. Use separate forms, or the form attribute to link a control to a form from elsewhere.
6. What does novalidate do?
It turns off the browser's built-in validation for the whole form. Use it only when you provide your own checks.
Key Takeawaysβ
<form>is the envelope: it holds the controls and decides where and how their data is sent.- Browsers collect a name and value pair from each control that has a
name, is not disabled, and has a value to send. - The key attributes are
action,method,enctype,target,autocomplete, andnovalidate. - A form is submitted by a submit button, the Enter key, or JavaScript. Keep one purpose per form, and never nest forms.
- Use
role="search"for search forms, name important forms for screen readers, and send private data withpostover HTTPS. - HTML only packages the data. A server must receive it, check it again, and act on it.
You now know what the envelope is. Next, learn how to write its address in Form Action, or return to the Forms overview.