HTML Forms: Collecting User Input
Forms are how websites collect information from users—from simple contact forms to complex checkout pages. In this tutorial, you’ll learn how to create forms with text inputs, dropdowns, checkboxes, and buttons. By the end, you’ll build a complete, working contact form!
What is an HTML Form?
Think of an HTML form like a paper form you might fill out at a doctor’s office. It has fields for your name, checkboxes for symptoms, and a place to sign. HTML forms work the same way—they provide spaces where users can type information, make selections, and submit their responses.
Every form you’ve ever used online—login pages, search boxes, shopping carts—is built with HTML form elements. Let’s learn how to create them!
Your First Form
All form elements must be wrapped in a <form> tag. Here’s the simplest possible form:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My First Form</title>
</head>
<body>
<h1>Contact Us</h1>
<form>
<label for="name">Your Name:</label>
<input type="text" id="name" name="name">
<button type="submit">Send</button>
</form>
</body>
</html>Breaking Down the Code
<form> — The container that wraps all your form elements. Without this, your inputs won’t work as a form.
<label> — Describes what each input is for. The for attribute connects it to an input’s id. When users click the label, it focuses the input—very helpful on mobile!
<input> — Creates an input field. The type attribute determines what kind of input it is (text, email, password, etc.). The name attribute identifies the data when the form is submitted. The id attribute connects it to its label.
<button type="submit"> — Creates a clickable button that submits the form.
Text Input Types
HTML provides many input types for different kinds of data. Using the right type helps users (especially on mobile) and provides basic validation:
<form>
<!-- Plain text input -->
<label for="username">Username:</label>
<input type="text" id="username" name="username">
<!-- Email input - shows email keyboard on mobile -->
<label for="email">Email:</label>
<input type="email" id="email" name="email">
<!-- Password input - hides characters -->
<label for="password">Password:</label>
<input type="password" id="password" name="password">
<!-- Number input - shows number keyboard -->
<label for="age">Age:</label>
<input type="number" id="age" name="age" min="0" max="120">
<!-- Phone input - shows phone keyboard on mobile -->
<label for="phone">Phone:</label>
<input type="tel" id="phone" name="phone">
<!-- URL input -->
<label for="website">Website:</label>
<input type="url" id="website" name="website">
<!-- Date picker -->
<label for="birthday">Birthday:</label>
<input type="date" id="birthday" name="birthday">
</form>Pro tip: Always use type="email" for email fields! Browsers will automatically check that users entered a valid email address, and mobile phones will show the @ symbol on the keyboard.
Adding Placeholder Text
Placeholder text shows example content inside an input before the user types. It disappears when they start typing:
<label for="email">Email Address:</label>
<input
type="email"
id="email"
name="email"
placeholder="[email protected]"
>Important: Don’t use placeholders as a replacement for labels! Placeholders disappear when users start typing, which can be confusing. Always include a visible <label>.
Making Fields Required
Add the required attribute to make a field mandatory. The form won’t submit until all required fields are filled in:
<label for="email">Email (required):</label>
<input
type="email"
id="email"
name="email"
required
>Multi-Line Text with Textarea
For longer text (like messages or comments), use <textarea> instead of <input>:
<label for="message">Your Message:</label>
<textarea
id="message"
name="message"
rows="5"
cols="40"
placeholder="Type your message here..."
></textarea>The rows and cols attributes set the initial size, but users can usually resize the textarea by dragging its corner.
Dropdown Menus with Select
When users need to choose from a predefined list of options, use a <select> dropdown:
<label for="country">Country:</label>
<select id="country" name="country">
<option value="">-- Please select --</option>
<option value="us">United States</option>
<option value="uk">United Kingdom</option>
<option value="ca">Canada</option>
<option value="au">Australia</option>
</select>The value attribute is what gets sent when the form submits. The text between the opening and closing <option> tags is what users see.
Grouping Options
For long lists, use <optgroup> to organize options into categories:
<label for="car">Choose a car:</label>
<select id="car" name="car">
<optgroup label="Swedish Cars">
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
</optgroup>
<optgroup label="German Cars">
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option>
</optgroup>
</select>Checkboxes
Checkboxes let users select multiple options (or none at all):
<p>What topics interest you?</p>
<input type="checkbox" id="html" name="interests" value="html">
<label for="html">HTML</label>
<input type="checkbox" id="css" name="interests" value="css">
<label for="css">CSS</label>
<input type="checkbox" id="javascript" name="interests" value="javascript">
<label for="javascript">JavaScript</label>Notice that checkboxes sharing the same name can all be selected independently. To pre-check a checkbox, add the checked attribute:
<input type="checkbox" id="newsletter" name="newsletter" value="yes" checked>
<label for="newsletter">Subscribe to newsletter</label>Radio Buttons
Radio buttons are like checkboxes, but users can only select ONE option from a group. All radio buttons in a group must share the same name:
<p>How would you rate our service?</p>
<input type="radio" id="excellent" name="rating" value="excellent">
<label for="excellent">Excellent</label>
<input type="radio" id="good" name="rating" value="good">
<label for="good">Good</label>
<input type="radio" id="average" name="rating" value="average">
<label for="average">Average</label>
<input type="radio" id="poor" name="rating" value="poor">
<label for="poor">Poor</label>Organizing Forms with Fieldset
For complex forms, use <fieldset> and <legend> to group related fields:
<form>
<fieldset>
<legend>Personal Information</legend>
<label for="firstname">First Name:</label>
<input type="text" id="firstname" name="firstname">
<label for="lastname">Last Name:</label>
<input type="text" id="lastname" name="lastname">
</fieldset>
<fieldset>
<legend>Contact Details</legend>
<label for="email">Email:</label>
<input type="email" id="email" name="email">
<label for="phone">Phone:</label>
<input type="tel" id="phone" name="phone">
</fieldset>
<button type="submit">Submit</button>
</form><fieldset> draws a box around the group, and <legend> provides a title. This is especially helpful for screen reader users!
Complete Contact Form Example
Let’s put everything together to build a complete, professional contact form:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Contact Us</title>
<style>
/* Basic styling to make the form look nice */
body {
font-family: Arial, sans-serif;
max-width: 600px;
margin: 40px auto;
padding: 20px;
}
h1 {
color: #333;
}
form {
background: #f9f9f9;
padding: 30px;
border-radius: 8px;
}
label {
display: block;
margin-top: 15px;
margin-bottom: 5px;
font-weight: bold;
}
input[type="text"],
input[type="email"],
input[type="tel"],
select,
textarea {
width: 100%;
padding: 10px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 16px;
box-sizing: border-box;
}
input:focus,
select:focus,
textarea:focus {
outline: none;
border-color: #007bff;
box-shadow: 0 0 5px rgba(0, 123, 255, 0.3);
}
.checkbox-group {
margin-top: 15px;
}
.checkbox-group label {
display: inline;
font-weight: normal;
margin-left: 8px;
}
button {
margin-top: 25px;
padding: 12px 30px;
background: #007bff;
color: white;
border: none;
border-radius: 4px;
font-size: 16px;
cursor: pointer;
}
button:hover {
background: #0056b3;
}
.required {
color: red;
}
</style>
</head>
<body>
<h1>Contact Us</h1>
<p>We'd love to hear from you! Fill out the form below and we'll get back to you within 24 hours.</p>
<form action="/submit" method="POST">
<label for="name">
Full Name <span class="required">*</span>
</label>
<input
type="text"
id="name"
name="name"
placeholder="John Smith"
required
>
<label for="email">
Email Address <span class="required">*</span>
</label>
<input
type="email"
id="email"
name="email"
placeholder="[email protected]"
required
>
<label for="phone">Phone Number</label>
<input
type="tel"
id="phone"
name="phone"
placeholder="+1 (555) 123-4567"
>
<label for="subject">Subject</label>
<select id="subject" name="subject">
<option value="">-- Please select --</option>
<option value="general">General Inquiry</option>
<option value="support">Technical Support</option>
<option value="billing">Billing Question</option>
<option value="feedback">Feedback</option>
<option value="other">Other</option>
</select>
<label for="message">
Your Message <span class="required">*</span>
</label>
<textarea
id="message"
name="message"
rows="6"
placeholder="Tell us how we can help..."
required
></textarea>
<div class="checkbox-group">
<input type="checkbox" id="newsletter" name="newsletter" value="yes">
<label for="newsletter">Subscribe to our newsletter for updates</label>
</div>
<button type="submit">Send Message</button>
</form>
</body>
</html>Form Attributes You Should Know
The <form> element has two important attributes that control where data goes:
action— The URL where form data is sent (e.g.,action="/submit")method— How data is sent:GET(in the URL) orPOST(in the request body)
<!-- Data sent via POST to /contact endpoint -->
<form action="/contact" method="POST">
...
</form>
<!-- Data sent via GET (appears in URL) -->
<form action="/search" method="GET">
<input type="text" name="q" placeholder="Search...">
<button type="submit">Search</button>
</form>When to use which method:
- POST — For contact forms, login forms, or any form that changes data on the server
- GET — For search forms or filters where you want the URL to be shareable
Accessibility Best Practices
Making forms accessible helps everyone, including people using screen readers or keyboard navigation:
- Always use labels — Every input must have a
<label>with a matchingfor/id - Use fieldsets for groups — Group related inputs (like radio buttons) with
<fieldset> - Indicate required fields — Add visual indicators AND use the
requiredattribute - Provide error messages — When validation fails, explain what went wrong clearly
- Use appropriate input types — This helps screen readers announce the expected format
Common Mistakes to Avoid
Avoid Missing Labels
<!-- Bad: No label! -->
<input type="email" placeholder="Email">
<!-- Good: Proper label -->
<label for="email">Email:</label>
<input type="email" id="email" name="email">Do Not Rely on Placeholder Text as a Label
<!-- Bad: Placeholder disappears when typing -->
<input type="text" placeholder="Your name">
<!-- Good: Label stays visible -->
<label for="name">Your name:</label>
<input type="text" id="name" name="name" placeholder="John Smith">Always Include the Name Attribute
<!-- Bad: Data won't be sent -->
<input type="email" id="email">
<!-- Good: Name identifies the data -->
<input type="email" id="email" name="email">Try It Yourself!
Now it’s your turn! Try these challenges to practice what you’ve learned:
- Basic: Create a newsletter signup form with just an email input and submit button
- Intermediate: Build a registration form with name, email, password, and a “terms and conditions” checkbox
- Advanced: Create a survey form with radio buttons, checkboxes, a dropdown, and a textarea for comments
Next Steps
Great job! You now know how to create HTML forms. To continue learning, check out these tutorials:
- Semantic HTML — Structure your pages for better accessibility
- HTML Tables — Display data in rows and columns
- Accessible Forms — Advanced accessibility techniques
- Contact Form Template — Ready-to-use form you can customize
đź’ˇ Practice Makes Perfect
Copy any code from this tutorial and try it in our free online HTML editor! Experiment with different input types, add more fields, and see your forms come to life instantly.