HTML Forms

Collect information from visitors with accessible, well-labelled forms.

Lesson 19 of 44Beginner12 min read

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

HTML
<form action="/subscribe" method="post">
  …controls…
</form>
  • action is where the data is sent, usually an address on a server.
  • method is how it is sent. With get, the data is added to the URL, which suits searches you might want to bookmark. With post, 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:

HTML
<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

ControlUse 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.
  • minlength and maxlength: limits on text length.
  • min and max: 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 the action address using the get or post method.
  • Connect every input to a <label> using matching for and id values.
  • Inputs without a name are not submitted.
  • Choose the control that fits the answer: text, textarea, select, checkbox or radio.
  • Attributes like required, min and pattern give you validation without JavaScript.

HTML Forms Examples

Each example runs in the page. Edit the code and press Run to see what changes.

Example 1

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>
ResultEdit the code, then press Run or Ctrl+Enter
Line-by-line explanation
  1. Line 1The form sends its data to /subscribe using POST.
  2. Lines 3 to 4The label's for matches the input's id. name="name" is the key the value is sent with.
  3. Lines 7 to 8type="email" and required add built-in validation. The placeholder is just a hint.
  4. Line 10A submit button sends the form.
Example 2

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>
ResultEdit the code, then press Run or Ctrl+Enter
Line-by-line explanation
  1. Lines 4 to 8A dropdown. Each <option> has a value that gets submitted; selected picks the default.
  2. Lines 11 to 15Radio buttons with the same name form a group, so only one can be picked. <fieldset> and <legend> label the group.
  3. Line 13Wrapping an input inside its label also connects them, so no for/id is needed.
  4. Line 19<textarea> for long text. minlength="10" asks for at least 10 characters.
  5. Line 22A single checkbox for an optional yes/no.

Common HTML Forms Mistakes

Inputs without labels

Don't
<input type="text" placeholder="Name">
Do
<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

Don't
<input id="city" type="text">
Do
<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

Don't
<input type="radio" name="size-s"> S
<input type="radio" name="size-m"> M
Do
<input type="radio" name="size" value="s"> S
<input type="radio" name="size" value="m"> M

Radios 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.

Fill in the blankseasy

Connect the label to the input.

<label ="phone">Phone number</label>
<input ="phone" name="phone" type="tel">
Multiple choiceeasy

Which attribute makes a field mandatory?

Multiple choicemedium

Which method should a login form use?

Fix the bugmedium

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>
ResultEdit the code, then press Run or Ctrl+Enter
Checks
  • The label is connected to the textarea
  • The textarea has a name
  • Both radios share the same name

HTML Forms Quiz

4 questions to check what you learned.

  1. Which element is used for a multi-line text box?

    • <input type="multiline">
    • <textarea>
    • <textbox>
    • <input rows="4">
  2. What happens to an input that has no name attribute 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"
  3. 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
  4. What is <legend> used for?

    • The title of a <fieldset> group
    • A form's footer text
    • Tooltip text for inputs
    • A map key

HTML Forms Challenge

Build a pizza order form

Make a form (action="/order", method="post") with:

  1. A labelled, required text input for the customer's name (name="customer")
  2. A <select name="size"> with Small, Medium and Large
  3. Two checkboxes for toppings, both with name="toppings"
  4. A submit button
<h2>Order a pizza</h2>
ResultEdit the code, then press Run or Ctrl+Enter
Checks
  • Form posts to /order
  • Required, labelled name input
  • Size select has 3 options
  • Two topping checkboxes
  • A submit button