Forms are how websites collect information from users — login boxes, search bars, contact pages, and checkouts are all built with the same handful of tags.
The <form> tag wraps all the inputs that belong together. Its two key attributes are action (where to send the data) and method (how to send it).
<form action="/submit" method="post">
<!-- inputs go here -->
</form>
method="get" — data is appended to the URL. Use for search forms.method="post" — data is sent in the request body. Use for anything sensitive (passwords, personal details).The <input> tag is self-closing and renders different controls depending on its type attribute. The most common is type="text".
Always pair every input with a <label>. The for attribute on the label must match the id on the input — this links them so clicking the label focuses the input, and screen readers announce what the field is for.
<label for="username">Username</label>
<input type="text" id="username" name="username" placeholder="e.g. jsmith">
The name attribute is what gets sent to the server — it’s the key in the key-value pair of form data.
Changing type gives you completely different controls, often with built-in validation.
<input type="text"> <!-- single line of text -->
<input type="email"> <!-- validates email format -->
<input type="password"> <!-- hides characters as typed -->
<input type="number"> <!-- numeric keyboard on mobile -->
<input type="date"> <!-- date picker -->
<input type="checkbox"> <!-- tick box -->
<input type="radio"> <!-- one choice from a group -->
<input type="file"> <!-- file upload picker -->
<input type="hidden"> <!-- invisible, sends data silently -->
Browsers handle validation for types like email, number, and date automatically — no JavaScript needed for basic checks.
Not everything is an <input>. Multi-line text uses <textarea>, dropdowns use <select> with <option> children, and submission uses <button>.
<!-- Multi-line text -->
<label for="message">Message</label>
<textarea id="message" name="message" rows="5"></textarea>
<!-- Dropdown -->
<label for="country">Country</label>
<select id="country" name="country">
<option value="ca">Canada</option>
<option value="us">United States</option>
<option value="uk">United Kingdom</option>
</select>
<!-- Submit button -->
<button type="submit">Send message</button>
Add required to any input to prevent the form from submitting if that field is empty. Combine it with the right type and the browser handles most common validation for free.
<input type="email" id="email" name="email" required>
<input type="text" id="name" name="name" required minlength="2" maxlength="50">
| Attribute | Purpose |
|---|---|
required | Field must not be empty |
minlength / maxlength | Character count limits (text) |
min / max | Value limits (number, date) |
placeholder | Hint text shown before typing |
disabled | Greys out the field, excludes from submission |
readonly | Visible but not editable |
<body>
<h1>Contact form</h1>
<form action="/submit" method="post">
<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="subject">Subject</label>
<select id="subject" name="subject">
<option value="general">General enquiry</option>
<option value="support">Support</option>
<option value="other">Other</option>
</select>
<label for="message">Message</label>
<textarea id="message" name="message" rows="5" required></textarea>
<button type="submit">Send message</button>
</form>
</body>
| Tag / Attribute | Purpose |
|---|---|
<form> | Form container |
<input> | Single-line control (self-closing) |
<textarea> | Multi-line text input |
<select> | Dropdown menu |
<option> | A choice inside a select |
<label> | Accessible label for an input |
<button type="submit"> | Submit the form |
name="..." | Key sent to the server |
required | Makes a field mandatory |
placeholder="..." | Hint text before input |
Next unit: Divs & spans — grouping elements for layout and styling.