HTML Form Basics
1. Introduction
Forms are the primary mechanism by which users send data to a server โ login pages, checkout flows, search bars, contact forms, and surveys all rely on HTML forms. Understanding how to structure a form correctly, choose the right action and method, and label controls for accessibility is foundational to building interactive web applications. This lesson walks you through every essential form element.
2. Concept
Form Submission Methods Compared
| Attribute | GET | POST |
|---|---|---|
| Data location | Appended to URL as query string | In the HTTP request body |
| Visibility | Visible in URL/browser history | Hidden from URL |
| Data size limit | ~2,048 characters (browser limit) | No practical limit |
| Use for | Search queries, filters (idempotent) | Logins, form submissions, file uploads |
| Bookmarkable? | Yes | No |
<label> element linked via the for attribute matching the control’s id. This is an accessibility requirement โ without it, screen reader users cannot identify what each field is for.<fieldset> with a <legend>. This is especially important for groups of radio buttons or checkboxes, which screen readers will announce as a single labelled group.3. Basic Example
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Contact Form</title>
</head>
<body>
<h1>Contact Us</h1>
<!-- action: URL to submit to; method: HTTP verb -->
<form action="/contact" method="post">
<!-- Label linked to input via for/id pair -->
<label for="name">Full Name</label>
<input type="text" id="name" name="name" required>
<label for="email">Email Address</label>
<input type="email" id="email" name="email" required>
<label for="message">Message</label>
<textarea id="message" name="message" rows="5" required></textarea>
<!-- Hidden field (not visible to user) -->
<input type="hidden" name="source" value="contact-page">
<button type="submit">Send Message</button>
<button type="reset">Clear Form</button>
</form>
</body>
</html>
4. How It Works
Step 1 โ The form Element
action="/contact" is the server URL that will receive the form data. method="post" sends the data in the HTTP request body. When the user submits, the browser serialises all named controls into key-value pairs.
Step 2 โ Label and Input Pairing
The for="name" attribute on <label> must exactly match the id="name" on the <input>. This creates a programmatic link: clicking the label focuses the input, and screen readers read the label when the input is focused.
Step 3 โ The name Attribute
The name attribute determines the key in the submitted data. Without it, a control’s value is not included in the submission. id is for CSS and JavaScript; name is for form submission.
Step 4 โ Button Types
type="submit" submits the form. type="reset" clears all fields to their default values. type="button" does nothing by default โ it must be wired up with JavaScript.
5. Real-World Example
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>User Registration</title>
</head>
<body>
<h1>Create Your Account</h1>
<form action="/register" method="post">
<fieldset>
<legend>Personal Information</legend>
<label for="first-name">First Name</label>
<input
type="text"
id="first-name"
name="first_name"
autocomplete="given-name"
required
aria-required="true"
>
<label for="last-name">Last Name</label>
<input
type="text"
id="last-name"
name="last_name"
autocomplete="family-name"
required
aria-required="true"
>
<label for="reg-email">Email Address</label>
<input
type="email"
id="reg-email"
name="email"
autocomplete="email"
required
aria-required="true"
aria-describedby="email-hint"
>
<p id="email-hint">We will never share your email.</p>
</fieldset>
<fieldset>
<legend>Account Security</legend>
<label for="password">Password</label>
<input
type="password"
id="password"
name="password"
autocomplete="new-password"
minlength="8"
required
>
</fieldset>
<input type="hidden" name="_csrf" value="abc123token">
<button type="submit">Create Account</button>
</form>
</body>
</html>
6. Common Mistakes
❌ Input with no label (uses placeholder only)
<input type="text" placeholder="Enter your name">
✓ Always link a label to every input
<label for="username">Username</label>
<input type="text" id="username" name="username" placeholder="e.g. jdoe">
❌ Using GET for password submission
<form action="/login" method="get">
<input type="password" name="pass">
</form>
✓ Always use POST for sensitive data
<form action="/login" method="post">
<input type="password" name="pass">
</form>
7. Try It Yourself
8. Quick Reference
| Element / Attribute | Purpose | Notes |
|---|---|---|
<form action method> |
Form container and submission config | action = URL; method = get/post |
<label for> |
Accessible control label | for must match input id |
<input name> |
Text/email/password/etc field | name = submission key |
<textarea> |
Multi-line text input | Rows/cols or CSS height |
<button type="submit"> |
Submit the form | Default type inside form |
required |
Browser-native validation | Boolean attribute |
autocomplete |
Browser autofill hints | Use WHATWG token values |