How do HTML forms work?

An HTML form collects user input and submits it to a server. Key attributes are action (where to send), method (GET or POST), and the name attributes on inputs.

HTML

Overview

HTML forms are the primary way to collect user input. A `<form>` element wraps input controls. When submitted, the browser packages the input values and sends them to the URL specified in `action` using the HTTP method in `method`.

Key Points

  • •`action`: the URL to submit data to. Omit or use `""` to submit to the current page.
  • •`method="GET"`: data goes in the URL query string (good for searches, bookmarkable).
  • •`method="POST"`: data goes in the request body (for passwords, large data, mutations).
  • •Every input needs a `name` attribute - that becomes the key in the submitted data.
  • •`<label for="id">` links a label to an input improves accessibility and click area.
  • •`required`, `minlength`, `type="email"` - use HTML5 built-in validation before reaching JavaScript.

Examples

Basic login form

html
<form action="/login" method="POST">
  <div>
    <label for="email">Email</label>
    <input type="email" id="email" name="email" required autocomplete="email" />
  </div>
  <div>
    <label for="password">Password</label>
    <input type="password" id="password" name="password" required minlength="8" />
  </div>
  <button type="submit">Log In</button>
</form>

Input types and their behaviour

html
<input type="text"     name="username" />
<input type="email"    name="email" />      <!-- validates email format -->
<input type="password" name="pass" />       <!-- hides characters -->
<input type="number"   name="age" min="0" max="120" />
<input type="checkbox" name="agree" value="yes" />
<input type="radio"    name="plan" value="free" />
<input type="file"     name="avatar" accept="image/*" />
<textarea              name="message" rows="4"></textarea>
<select                name="country">
  <option value="us">United States</option>
</select>

Prevent default and handle with JavaScript

javascript
document.querySelector('form').addEventListener('submit', async (e) => {
  e.preventDefault(); // stop the browser from navigating

  const data = new FormData(e.target);
  const body = Object.fromEntries(data); // { email: '...', password: '...' }

  const res = await fetch('/login', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(body),
  });
});

Pro Tip

Use `<label for="...">` for every input always. It increases click targets (clicking the label focuses the input) and is essential for screen readers. Pairing a label with a visible placeholder is fine, but never use placeholder as the only label - it disappears when the user types.