HTML Tutorial · Page Structure · Lesson 15 of 34
HTML Forms
Collect user input with form, label, input, select, textarea and button.
The form element
A <form> groups inputs and sends them to a server: action is the URL and method is get (data in the URL — searches) or post (data in the body — sign-ups, payments).
<style>
form { display: grid; gap: 10px; max-width: 320px; font-family: sans-serif; }
label { display: grid; gap: 4px; font-size: 0.9em; }
label:has(input[type="radio"], input[type="checkbox"]) { display: flex; align-items: center; gap: 6px; }
fieldset { border: 1px solid #cbd5e1; border-radius: 6px; }
</style>
<form action="/subscribe" method="post" onsubmit="event.preventDefault(); this.querySelector('output').value = 'Submitted (demo)';">
<label>Name <input name="name" autocomplete="name"></label>
<label for="email">Email</label>
<input id="email" name="email" type="email">
<label>Topic
<select name="topic">
<option>HTML</option>
<option selected>CSS</option>
<option>JavaScript</option>
</select>
</label>
<fieldset>
<legend>Frequency</legend>
<label><input type="radio" name="freq" value="weekly" checked> Weekly</label>
<label><input type="radio" name="freq" value="monthly"> Monthly</label>
</fieldset>
<label>Message <textarea name="message" rows="3"></textarea></label>
<label><input type="checkbox" name="terms"> I agree to the terms</label>
<button>Subscribe</button>
<output></output>
</form>
Labels
Every input needs a <label>. Connect them with for and id (or wrap the input inside the label). Clicking the label focuses the input, and screen readers announce it.
Other controls
<textarea>— multi-line text.<select>with<option>s — a dropdown.<input type="checkbox">and<input type="radio">(radios share aname).<fieldset>+<legend>— group related controls.<button>— submits by default; usetype="button"for buttons that only run JavaScript.
Test yourself
How do you connect a <label> to an <input>?
Placing them next to each otherMatching the label's for with the input's idUsing the same classUsing name on both
Show answer
Answer: Matching the label's for with the input's id