Forms are how websites listen. Search boxes, contact forms, checkouts, surveys and comment boxes are all forms. In HTML, a form is a <form> element that contains controls such as text boxes, dropdowns, checkboxes and a submit button.
A well-built form is short, clearly labelled and tells people about mistakes before they press send. A badly built one is the quickest way to lose a visitor. Most of the work of a good form is done by plain HTML, before any JavaScript is involved.
In this lesson you'll build forms that are easy to use, work for keyboard and screen-reader users, and check the input for you without a single line of JavaScript.
The form element: action and method
<form action="/subscribe" method="post">
…controls…
</form>actionis where the data is sent, usually an address on a server.methodis how it is sent. Withget, the data is added to the URL, which suits searches you might want to bookmark. Withpost, the data travels in the body of the request, which is right for anything private or anything that changes data, such as placing an order.
On its own, HTML can't store or email form data. A server-side program, or a form service, receives the data at the action address and decides what to do with it.
Labels: never skip them
Every input needs a <label>. Connect the two by giving the input an id and the label a matching for:
<label for="email">Email</label>
<input id="email" name="email" type="email">Now clicking the label puts the cursor in the box, and screen readers announce "Email, edit text". Placeholder text is not a replacement for a label. It disappears as soon as you start typing, so people forget what the box was for.
The name attribute
name is the key the data is sent with. If an input has no name, its value is not submitted at all. Think of it as the column heading in a spreadsheet of answers: email=sam@example.com.
The main form controls
| Control | Use for |
|---|---|
<input type="text"> | Short text: name, city |
<textarea> | Long text: messages, comments |
<select> + <option> | Choose one from a list |
<input type="checkbox"> | Yes/no, or several choices |
<input type="radio"> | Exactly one choice from a few |
<button type="submit"> | Send the form |
You'll meet all the input types in HTML Input Types.
Built-in form validation
Browsers check a form before sending it if you add the right attributes:
required: the field can't be empty.minlengthandmaxlength: limits on text length.minandmax: limits on a number range.pattern: a custom rule written as a regular expression.type="email": the value must look like an email address.
Try submitting the examples below with empty fields. Remember that browser checks help the visitor, but a server must always check the data again, because anyone can bypass the browser.
HTML Forms Syntax
A labelled field
<form action="/send" method="post">
<label for="id">Label text</label>
<input id="id" name="fieldname" type="text" required>
<button type="submit">Send</button>
</form>HTML Forms Summary
- A
<form>sends its data to theactionaddress using thegetorpostmethod. - Connect every input to a
<label>using matchingforandidvalues. - Inputs without a
nameare not submitted. - Choose the control that fits the answer: text, textarea, select, checkbox or radio.
- Attributes like
required,minandpatterngive you validation without JavaScript.
HTML Forms Examples
Each example runs in the page. Edit the code and press Run to see what changes.
A newsletter form
Press Subscribe with the fields empty, then with a bad email like sam@. The browser stops you both times.
<form action="/subscribe" method="post">
<p>
<label for="name">Your name</label><br>
<input id="name" name="name" type="text" required>
</p>
<p>
<label for="email">Email address</label><br>
<input id="email" name="email" type="email" placeholder="you@example.com" required>
</p>
<button type="submit">Subscribe</button>
</form>Line-by-line explanation
- Line 1The form sends its data to
/subscribeusing POST. - Lines 3 to 4The label's
formatches the input'sid.name="name"is the key the value is sent with. - Lines 7 to 8
type="email"andrequiredadd built-in validation. The placeholder is just a hint. - Line 10A submit button sends the form.
A contact form with every control
<form action="/contact" method="post">
<p>
<label for="topic">Topic</label><br>
<select id="topic" name="topic">
<option value="order">My order</option>
<option value="bug">Report a bug</option>
<option value="other" selected>Something else</option>
</select>
</p>
<fieldset>
<legend>How should we reply?</legend>
<label><input type="radio" name="reply" value="email" checked> Email</label>
<label><input type="radio" name="reply" value="phone"> Phone</label>
</fieldset>
<p>
<label for="msg">Message</label><br>
<textarea id="msg" name="message" rows="4" cols="34" minlength="10" required></textarea>
</p>
<p><label><input type="checkbox" name="updates"> Send me product news</label></p>
<button type="submit">Send message</button>
</form>Line-by-line explanation
- Lines 4 to 8A dropdown. Each
<option>has avaluethat gets submitted;selectedpicks the default. - Lines 11 to 15Radio buttons with the same name form a group, so only one can be picked.
<fieldset>and<legend>label the group. - Line 13Wrapping an input inside its label also connects them, so no
for/idis needed. - Line 19
<textarea>for long text.minlength="10"asks for at least 10 characters. - Line 22A single checkbox for an optional yes/no.
Common HTML Forms Mistakes
Inputs without labels
<input type="text" placeholder="Name"><label for="fullname">Name</label>
<input id="fullname" name="fullname" type="text">Placeholders vanish when you type and are often low contrast. Screen readers may not announce them. Always use a real label.
Forgetting name
<input id="city" type="text"><input id="city" name="city" type="text">No name means the value is never sent. This bug is invisible until you check the server!
Radio buttons with different names
<input type="radio" name="size-s"> S
<input type="radio" name="size-m"> M<input type="radio" name="size" value="s"> S
<input type="radio" name="size" value="m"> MRadios only work as a "pick one" group when they share the same name.
HTML Forms in Real Projects
Forms everywhere
Every login, search box, checkout, survey and booking system is built on these elements. Large sites add JavaScript for extra checks and friendlier messages (see JavaScript Events), but they always start from a solid HTML form, so it still works if the script fails.
HTML Forms Exercises
Answer each one and check it instantly. If you get stuck, open the hint before the answer.
Connect the label to the input.
<label ="phone">Phone number</label>
<input ="phone" name="phone" type="tel">
for matches the input's id.Which attribute makes a field mandatory?
required stops the form submitting while the field is empty.Which method should a login form use?
This feedback form has three problems: the label isn't connected, the textarea has no name, and the radio buttons don't form a group. Fix them.
<form action="/feedback" method="post">
<label>Your comment</label>
<textarea id="comment"></textarea>
<p>Rating:
<label><input type="radio" name="good" value="good"> Good</label>
<label><input type="radio" name="bad" value="bad"> Bad</label>
</p>
<button type="submit">Send</button>
</form>- The label is connected to the textarea
- The textarea has a name
- Both radios share the same name
for, values need a name to be sent, and radios group by sharing a name.for + id, add name, and give both radios one shared name.HTML Forms Quiz
4 questions to check what you learned.
Which element is used for a multi-line text box?
<input type="multiline"><textarea><textbox><input rows="4">
What happens to an input that has no
nameattribute when the form is submitted?- It's sent with a random name
- The form refuses to submit
- Its value isn't sent at all
- It's sent as "undefined"
How do you make radio buttons a "choose one" group?
- Put them in a
<ul> - Give them the same
id - Use
type="group" - Give them the same
name
- Put them in a
What is
<legend>used for?- The title of a
<fieldset>group - A form's footer text
- Tooltip text for inputs
- A map key
- The title of a
HTML Forms Challenge
Build a pizza order form
Make a form (action="/order", method="post") with:
- A labelled, required text input for the customer's name (
name="customer") - A
<select name="size">with Small, Medium and Large - Two checkboxes for toppings, both with
name="toppings" - A submit button
<h2>Order a pizza</h2>
- Form posts to /order
- Required, labelled name input
- Size select has 3 options
- Two topping checkboxes
- A submit button