HTML Forms

HTML · Lesson 23 of 35 7 min read Updated

Sign-up pages, search boxes, feedback pages and checkout pages are all forms. A form is a part of the page that collects input from the user and sends it somewhere, usually to a server that stores it or answers it.

In this lesson you will learn how a form is built, why every input needs a label and a name, what the browser sends when the user clicks Submit, and how to choose between GET and POST.

How a form works

Every form follows the same three steps:

  1. The user fills in form controls: text boxes, checkboxes, drop-downs and so on.
  2. The user submits the form, usually by clicking a button or pressing Enter.
  3. The browser collects each control's name and value, and sends them to the URL in the form's action attribute, using the HTTP method in its method attribute.
HTML
<form action="/register" method="post">
  <!-- form controls go here -->
</form>
  • action is the URL that receives the data. If you leave it out, the data goes to the current page's URL.
  • method is get or post. If you leave it out, the browser uses get.

Forms cannot be nested: never put one <form> inside another.

Labels and inputs

The most common control is <input>, a single-line box. Every input needs a <label> that says what to type. Connect them by giving the input an id and the label a matching for attribute.

HTML
<label for="full-name">Full name</label>
<input id="full-name" name="full-name">

<!-- Or wrap the input inside the label -->
<label>
  City
  <input name="city">
</label>

A proper label does two jobs. Screen readers read it aloud when the input gets focus, and clicking the label text moves focus into the input, which gives people on phones a bigger target to tap.

The name attribute decides what is sent

When the form is submitted, the browser sends one name=value pair for each control. The name comes from the control's name attribute and the value is what the user entered. A control without a name is not sent at all, which is a very common bug.

The example below has a short script that stops the real submission and shows you exactly what the browser would send instead. You do not need to understand the script yet; you will learn it in JavaScript Forms.

HTMLTry it yourself
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Feedback</title>
</head>
<body>
  <h1>Canteen feedback</h1>
  <form action="#" method="post">
    <p>
      <label for="student">Your name</label>
      <input id="student" name="student">
    </p>
    <p>
      <label for="dish">Favourite dish</label>
      <input id="dish" name="dish">
    </p>
    <p>
      <label for="note">Comment (not sent, no name)</label>
      <input id="note">
    </p>
    <button>Send feedback</button>
  </form>

  <p>Data the browser would send: <output id="sent"></output></p>

  <script>
    const form = document.querySelector("form");
    form.addEventListener("submit", (event) => {
      event.preventDefault(); // demo only: stop the real submission
      document.querySelector("#sent").textContent =
        new URLSearchParams(new FormData(form)).toString();
    });
  </script>
</body>
</html>

Type "Priya Sharma" and "Masala dosa", then submit. You will see student=Priya+Sharma&dish=Masala+dosa. Spaces become + and special characters are encoded so they can travel safely in a URL. The comment box is missing because it has no name.

GET or POST?

The method decides where the name=value pairs travel.

method="get"method="post"
Where the data goesAdded to the URL after a ?Sent in the body of the request
Visible in the address barYesNo
Can be bookmarked or sharedYesNo
Good forSearch boxes, filters, sortingSign-ups, logins, orders, anything that changes data

A GET search for trains might produce a URL such as /trains?from=Jaipur&to=Pune. That is perfect for a search, because the user can bookmark the results. It is terrible for a password, which would end up in the browser history and server logs.

Neither method encrypts anything. POST only keeps the data out of the URL. To protect data while it travels, the site must use HTTPS.

Buttons

A <button> inside a form has a type attribute with three possible values:

  • type="submit" submits the form. This is the default, so a plain <button> in a form is a submit button.
  • type="button" does nothing on its own. Use it for buttons that run JavaScript, such as "Show password".
  • type="reset" clears every field back to its starting value. Users press it by accident and lose their work, so it is rarely a good idea.

Pressing Enter inside a text input also submits the form, so short forms work smoothly from the keyboard.

HTMLTry it yourself
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Train Search</title>
</head>
<body>
  <h1>Search trains</h1>
  <form action="#" method="get">
    <label for="from">From</label>
    <input id="from" name="from" value="Jaipur">
    <label for="to">To</label>
    <input id="to" name="to">
    <button type="button" id="swap">Swap</button>
    <button type="submit">Search</button>
  </form>
  <p>A GET form would load: <output id="url"></output></p>

  <script>
    const form = document.querySelector("form");
    document.querySelector("#swap").addEventListener("click", () => {
      [form.from.value, form.to.value] = [form.to.value, form.from.value];
    });
    form.addEventListener("submit", (event) => {
      event.preventDefault(); // demo only
      document.querySelector("#url").textContent =
        "/trains?" + new URLSearchParams(new FormData(form));
    });
  </script>
</body>
</html>

The Swap button has type="button", so it swaps the two cities without submitting. Try removing type="button" from it: now clicking Swap submits the form too.

Where does the data go?

HTML only builds the form and sends the data. Something on the server must receive it, check it and store it. In this course, examples use action="#" and a small script so nothing is sent anywhere real. When you are ready, PHP Form Handling shows how a server reads the values, and Input Types shows the many kinds of input you can collect.

Common mistakes

  • Missing name attributes. The field looks fine but its value never reaches the server.
  • for and id that do not match. The label is no longer connected, so clicking it does nothing and screen readers stay silent.
  • Using GET for private data. Passwords and personal details must use POST over HTTPS.
  • A plain <button> that should not submit. Add type="button" to buttons that only run JavaScript.

Key points

  • A <form> sends name=value pairs to the URL in action using the method in method.
  • Connect every input to a visible <label> with matching for and id attributes.
  • Only controls with a name attribute are sent.
  • Use GET for searches and filters, POST for anything private or that changes data, and HTTPS for both.
  • A <button> in a form submits by default; use type="button" for script-only buttons.

Exercise

Create a newsletter sign-up form that uses POST. It needs a labelled input for the subscriber's name and one for their city, and a submit button that says "Subscribe". Add the demo script from this lesson so that submitting shows the data the browser would send. Make sure both values appear.

Show solution
HTML
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Newsletter</title>
</head>
<body>
  <form action="#" method="post">
    <p>
      <label for="sub-name">Name</label>
      <input id="sub-name" name="name">
    </p>
    <p>
      <label for="sub-city">City</label>
      <input id="sub-city" name="city">
    </p>
    <button type="submit">Subscribe</button>
  </form>
  <p>Would send: <output id="sent"></output></p>

  <script>
    const form = document.querySelector("form");
    form.addEventListener("submit", (event) => {
      event.preventDefault();
      document.querySelector("#sent").textContent =
        new URLSearchParams(new FormData(form)).toString();
    });
  </script>
</body>
</html>

Both inputs have a name, so both appear in the output, for example name=Meera&city=Lucknow.

Quick Quiz

1. Which attribute decides the name in each name=value pair that a form sends?

2. What is the default type of a <button> inside a form?

3. Which method should a login form use?

4. Why is a placeholder not enough instead of a label?

Learn HTML with a mentor

Free lessons get you started. Our Full Stack Web Development training adds real projects and code reviews from working developers.

  • Project-based learning
  • Mentor code reviews
  • Free counselling call