Forms: User Input
Building forms with input, label, textarea, select, and button
Forms are how the web collects information — login pages, search bars, checkout flows, contact forms. Without forms, the web would be read-only. This module covers every tag you need to build them properly.
The Form Container (<form>)
The <form> tag wraps everything and does the most important job: packaging the user's data and sending it to a destination. Think of it as a mailing envelope — you put the letter inside, write the address on the front, and choose how to send it.
<form action="/submit-contact" method="POST">
<!-- all inputs go here -->
</form>
Key Attributes
action — The URL where data is sent when the user submits:
<form action="/login">
method — How the data travels:
| Method | Behaviour | Use for |
|---|---|---|
GET |
Data appears in the URL (?q=cats) |
Search bars, filters |
POST |
Data is hidden inside the request | Passwords, private info, file uploads |
Security: Never use
GETfor passwords or sensitive data. Anyone can see URL parameters in browser history, server logs, and over the shoulder.
Pro tip: If you forget the
<form>wrapper and just place inputs on the page, the Submit button won't know where to send anything. The button looks for its<form>parent to find theactionURL.
The Input Element (<input>)
The <input> tag is the most versatile tag in HTML. By changing just one attribute (type), it transforms from a text box into a checkbox, calendar, file uploader, or color picker. It is a void element — no closing tag.
Common Input Types
<!-- Single-line text -->
<input type="text" name="username" placeholder="Enter your name">
<!-- Password (hides characters) -->
<input type="password" name="password" placeholder="Password">
<!-- Email (validates format on submit) -->
<input type="email" name="email" placeholder="you@example.com">
<!-- Number (blocks letters, adds up/down arrows) -->
<input type="number" name="age" min="1" max="120">
<!-- Date (opens a calendar picker) -->
<input type="date" name="birthday">
<!-- Colour picker -->
<input type="color" name="theme" value="#0d9488">
<!-- Range slider -->
<input type="range" name="volume" min="0" max="100" step="5" value="50">
<!-- File upload -->
<input type="file" name="avatar" accept="image/*">
<!-- Hidden field — submitted but not visible -->
<input type="hidden" name="csrf_token" value="abc123">
Essential Input Attributes
| Attribute | Effect |
|---|---|
name |
Critical. Labels the data for the server. Like tagging a box "Apple: 1, Banana: 2" |
placeholder |
Grey ghost text that disappears when you start typing |
required |
Blocks form submission if empty; browser shows a warning |
value |
Pre-fills the input with a default value |
minlength / maxlength |
Text length constraints |
min / max |
Numeric or date range limits |
pattern |
Validates against a regular expression |
disabled |
Greys out the field; user cannot interact |
readonly |
Shows the value but prevents editing |
<input
type="email"
name="user_email"
placeholder="john@example.com"
required
>
The Label Element (<label>)
The <label> tag defines the visible name for an input. Think of a cockpit dashboard with 50 unlabelled switches — without labels, you don't know which one controls what.
Connecting Label to Input
You must link them explicitly using for and id:
<label for="username">Enter your Username:</label>
<input type="text" id="username" name="user_name">
- Give the input a unique
id - Set the label's
forattribute to that sameid
Why this matters:
- Clickability: Clicking the label text focuses or toggles the input. Critical for mobile users — a tiny checkbox is much easier to hit when the whole label is also a target.
- Screen readers: When a blind user's cursor lands on the input, the screen reader reads the label aloud. Without a label, it says "Edit text blank" — the user has no idea what to type.
Checkboxes & Radio Buttons
Checkboxes — Select any number of options
<p>Pick your toppings:</p>
<label><input type="checkbox" name="topping" value="cheese"> Cheese</label>
<label><input type="checkbox" name="topping" value="pepperoni"> Pepperoni</label>
<label><input type="checkbox" name="topping" value="mushrooms"> Mushrooms</label>
Radio Buttons — Select exactly one option
Radio buttons with the same name are grouped. Selecting one automatically deselects the others — like a car radio where only one station can play at a time.
<p>Pick your size:</p>
<label><input type="radio" name="size" value="small"> Small</label>
<label><input type="radio" name="size" value="medium"> Medium</label>
<label><input type="radio" name="size" value="large"> Large</label>
Textarea (<textarea>)
A multi-line text box — for comments, bios, reviews, or any long-form input. Unlike <input>, it has a closing tag and the default text goes between the tags.
<label for="story">Tell us your story:</label>
<textarea id="story" name="user_story" rows="5" placeholder="Write something..."></textarea>
| Attribute | Effect |
|---|---|
rows |
Default visible height (in lines) |
cols |
Default visible width (usually overridden with CSS) |
placeholder |
Ghost text hint |
required |
Blocks submission if empty |
Dropdown Menus (<select> and <option>)
A collapsible list of choices — useful for countries, states, years, or any long list where radio buttons would take too much space.
<label for="country">Choose a country:</label>
<select id="country" name="country">
<option value="">-- Select --</option>
<option value="in">India</option>
<option value="us">United States</option>
<option value="uk">United Kingdom</option>
<option value="ca" selected>Canada</option>
</select>
Add selected to an <option> to pre-select it. Add multiple to the <select> to allow selecting more than one option.
The Button Element (<button>)
The <button> tag creates a clickable button. Its behaviour depends entirely on its type attribute.
<form>
<!-- Submits the form -->
<button type="submit">Send Message</button>
<!-- Clears all inputs back to default -->
<button type="reset">Clear Form</button>
<!-- Does nothing by default — for JavaScript -->
<button type="button">Preview</button>
</form>
Warning:
type="reset"erases everything the user has typed. Most modern applications avoid this — accidentally clicking it is extremely frustrating.
Pro tip:
type="button"is a "blank canvas" button. Attach a JavaScriptonclickhandler to make it do whatever you need — open a modal, toggle a menu, calculate a result.
A Complete Contact Form
<form action="/contact" method="POST">
<label for="name">Full Name *</label>
<input type="text" id="name" name="name" required placeholder="Jane Doe">
<label for="email">Email Address *</label>
<input type="email" id="email" name="email" required placeholder="jane@example.com">
<label for="subject">Subject</label>
<select id="subject" name="subject">
<option value="general">General Enquiry</option>
<option value="support">Technical Support</option>
<option value="feedback">Feedback</option>
</select>
<label for="message">Message *</label>
<textarea id="message" name="message" rows="5" required placeholder="Your message..."></textarea>
<button type="submit">Send Message</button>
</form>