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"></form>
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>