Forms: form, input, label and button

Build a working form, connect every label to its control, and see exactly what gets sent.

  • Beginner
  • 6 min read
  • Updated 17 Oct 2026

What you will learn

  • Build a labelled form
  • Explain what is sent when a form submits
  • Choose between GET and POST

Forms are how people send information to a website: searches, sign-ups, bookings and payments. HTML forms work without any JavaScript. The browser collects the values, packages them and sends them to a URL, and it handles keyboard use, autofill and validation for you.

A complete form

HTML
<!DOCTYPE html>
<html lang="en-GB">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Join the newsletter | Riverside Bakery</title>
</head>
<body>
  <h1>Join the newsletter</h1>
  <form action="/newsletter" method="post">
    <p>
      <label for="name">Your name</label>
      <input id="name" name="name" type="text">
    </p>
    <p>
      <label for="email">Email address</label>
      <input id="email" name="email" type="email" required>
    </p>
    <button type="submit">Subscribe</button>
  </form>
</body>
</html>

The rest of this lesson explains each part.

The form element

form wraps the controls that are submitted together.

  • action is the URL that receives the data. If you leave it out, the form submits to the current page's URL.
  • method is the HTTP method: get or post. The default is get.

GET or POST?

MethodData goes inUse for
getThe URL: /search?q=ryeSearches and filters, anything safe to bookmark or share
postThe request bodyAnything that creates or changes data: sign-ups, orders, messages

GET requests can be cached, bookmarked and repeated without side effects. Never use GET for passwords or personal data, because the values appear in the address bar, browser history and server logs.

The input element

input is the most versatile form control. Its type attribute decides what kind of control it is: text, email, password, checkbox, radio, date and many more. The default is text. The next lesson covers the types.

input is a void element, so it has no closing tag. Its current value can be preset with the value attribute:

HTML
<input id="town" name="town" type="text" value="Bristol">

The name attribute decides what is sent

When a form submits, the browser sends each control's name with its current value. A control without a name is not submitted at all. This is the most common reason "my form does not send the field".

Fill in the form above with "Sam" and "sam@example.com" and submit it. With method="get", the browser would request:

Plain text
/newsletter?name=Sam&email=sam%40example.com

With method="post", the same name=value pairs travel in the request body instead. Special characters such as @ and spaces are encoded automatically.

The id and the name do different jobs. id identifies the element in the page, for labels, CSS and JavaScript. name is the key the server receives. They are often the same, but they do not have to be.

To see what a form sends, open DevTools, go to the Network panel, submit the form and click the request. The Payload tab shows every name and value.

Labels

Every control needs a label: visible text that says what to enter. Connect the two with for on the label and the matching id on the control:

HTML
<label for="email">Email address</label>
<input id="email" name="email" type="email">

A connected label does three things:

  • Screen readers announce "Email address, edit text" when the field receives focus. Without the connection, they announce only "edit text".
  • Clicking or tapping the label focuses the field. For checkboxes and radio buttons, it toggles them, which gives a much bigger target.
  • Voice control users can say "click Email address".

You can also wrap the control inside the label, with no for or id needed:

HTML
<label>
  Email address
  <input name="email" type="email">
</label>

Both forms work. The for and id version is more flexible for styling and layout.

placeholder is not a label. It disappears when someone starts typing, is often low in contrast, and is not reliably announced by every screen reader. Use a real label, and use the placeholder, if at all, for a short example of the format.

Buttons

button submits the form by default:

HTML
<button type="submit">Subscribe</button>

The type attribute has three values:

TypeWhat it does
submitSubmits the form. This is the default inside a form.
resetClears every control back to its initial value. Rarely useful and easy to click by mistake.
buttonDoes nothing on its own. Use it for buttons that run JavaScript.

Always set type explicitly. A button meant to open a menu but left without type="button" will submit the form when clicked.

Pressing Enter in a text field also submits the form. That is expected behaviour, called implicit submission, and it works reliably when the form has a submit button.

You may also see <input type="submit" value="Subscribe">. It works, but button can contain other elements, such as an icon, and is easier to style.

Disabled and read-only

  • disabled greys out a control, removes it from the tab order, and does not submit its value.
  • readonly lets people see and select the value but not change it, and the value is submitted.

What the browser does not do

HTML collects and sends data. It does not store anything. Something on the server must receive the request, check the data and act on it: a PHP script, a WordPress plugin, a serverless function or a form service. Always validate on the server too, because anyone can send any data to your action URL, whatever your HTML allows.

Summary

  • form wraps the controls; action sets the URL and method sets GET or POST.
  • Use GET for searches and POST for anything that changes data.
  • Only controls with a name are submitted.
  • Give every control a visible label connected with for and id.
  • Set type on every button, and validate on the server as well as in the browser.

Further reading