Forms are how users submit data to your website. From login pages to search boxes to complex surveys, forms are everywhere on the web. This tutorial covers form elements, validation, and best practices.
What you’ll learn:
The <form> element and attributes
Input types and the <input> element
Other form elements: <textarea>, <select>, <button>
Labels and accessibility
Form validation and required attributes
File uploads and date pickers
Best practices for user experience
Prerequisites:
Every form starts with the <form> element:
Interactive code playground requires JavaScript. Here's the code:
<form action="/submit" method="POST">
<!-- Form elements go here -->
</form>
The <form> element has two critical attributes:
action : Where the form data is sent
method : How the data is sent (usually POST or GET)
The <input> element is the most common form element. Different types handle different data:
Interactive code playground requires JavaScript. Here's the code:
<form>
<label for="username">Username:</label>
<input type="text" id="username" name="username">
<label for="email">Email:</label>
<input type="email" id="email" name="email">
<label for="password">Password:</label>
<input type="password" id="password" name="password">
</form>
Interactive code playground requires JavaScript. Here's the code:
<form>
<label for="age">Age:</label>
<input type="number" id="age" name="age" min="0" max="120">
<label for="satisfaction">Satisfaction (1-10):</label>
<input type="range" id="satisfaction" name="satisfaction" min="1" max="10">
</form>
Use type="number" for numeric input with validation. type="range" creates a slider.
Interactive code playground requires JavaScript. Here's the code:
<form>
<fieldset>
<legend>What are your interests?</legend>
<label>
<input type="checkbox" name="interests" value="sports">
Sports
</label>
<label>
<input type="checkbox" name="interests" value="music">
Music
</label>
<label>
<input type="checkbox" name="interests" value="reading">
Reading
</label>
</fieldset>
<fieldset>
<legend>What's your experience level?</legend>
<label>
<input type="radio" name="experience" value="beginner">
Beginner
</label>
<label>
<input type="radio" name="experience" value="intermediate">
Intermediate
</label>
<label>
<input type="radio" name="experience" value="expert">
Expert
</label>
</fieldset>
</form>
Checkboxes : Multiple selections allowed
Radio buttons : Only one selection allowed
<fieldset> and <legend> : Group related inputs and label the group
Interactive code playground requires JavaScript. Here's the code:
<form>
<label for="birthday">Birthday:</label>
<input type="date" id="birthday" name="birthday">
<label for="meeting-time">Meeting time:</label>
<input type="time" id="meeting-time" name="meeting-time">
<label for="start-date">Start date:</label>
<input type="datetime-local" id="start-date" name="start-date">
</form>
These show calendar and time pickers on most devices. Users appreciate these instead of typing dates.
Interactive code playground requires JavaScript. Here's the code:
<form>
<label for="profile-pic">Upload profile picture:</label>
<input type="file" id="profile-pic" name="profile-pic" accept="image/*">
<label for="resume">Upload resume (PDF only):</label>
<input type="file" id="resume" name="resume" accept=".pdf">
</form>
Use accept to limit file types. Common values:
"image/*" — Any image format
".pdf" — PDF files only
".jpg,.png" — Specific formats
Interactive code playground requires JavaScript. Here's the code:
<form>
<label for="website">Website:</label>
<input type="url" id="website" name="website">
<label for="phone">Phone:</label>
<input type="tel" id="phone" name="phone">
<label for="color">Favorite color:</label>
<input type="color" id="color" name="color">
<label for="search">Search:</label>
<input type="search" id="search" name="search">
</form>
Each type provides appropriate input methods and validation.
For longer text like comments or messages:
Interactive code playground requires JavaScript. Here's the code:
<form>
<label for="comments">Comments:</label>
<textarea id="comments" name="comments" rows="4" cols="40">
Enter your comments here...
</textarea>
</form>
The rows and cols attributes set the initial size (though users can resize).
For choosing from predefined options:
Interactive code playground requires JavaScript. Here's the code:
<form>
<label for="country">Select your country:</label>
<select id="country" name="country">
<option value="">-- Please select --</option>
<option value="usa">United States</option>
<option value="canada">Canada</option>
<option value="mexico">Mexico</option>
<option value="other">Other</option>
</select>
<label for="category">Category:</label>
<select id="category" name="category" multiple>
<option value="tech">Technology</option>
<option value="business">Business</option>
<option value="health">Health</option>
</select>
</form>
Add multiple attribute to allow selecting multiple options
The first <option> with empty value is often a placeholder
Use <optgroup> to organize options:
< optgroup label = " Romance Languages " >
< option value = " es " > Spanish </ option >
< option value = " fr " > French </ option >
< optgroup label = " Germanic Languages " >
< option value = " de " > German </ option >
< option value = " en " > English </ option >
Always connect labels to inputs with the for attribute:
Interactive code playground requires JavaScript. Here's the code:
<form>
<!-- Good: Label connected to input -->
<label for="name">Name:</label>
<input type="text" id="name" name="name">
<!-- Good: Input inside label -->
<label>
Email:
<input type="email" name="email">
</label>
<!-- Bad: Label not connected -->
<label>Name:</label>
<input type="text" name="name">
</form>
Connected labels:
Make forms easier to use (larger click area)
Help screen readers announce the label
Are required for accessibility
HTML5 provides built-in validation. Mark fields as required and specify patterns:
Interactive code playground requires JavaScript. Here's the code:
<form>
<label for="username">Username:</label>
<input type="text" id="username" name="username" required minlength="3" maxlength="20">
<label for="email">Email:</label>
<input type="email" id="email" name="email" required>
<label for="age">Age:</label>
<input type="number" id="age" name="age" required min="18" max="120">
<label for="password">Password:</label>
<input type="password" id="password" name="password" required minlength="8">
<button type="submit">Create Account</button>
</form>
Validation attributes:
required : Field must be filled
minlength/maxlength : String length limits
min/max : Number or date limits
pattern : Regular expression pattern
type="email" : Validates email format
Forms need buttons for submission and other actions:
Interactive code playground requires JavaScript. Here's the code:
<form>
<label for="email">Email:</label>
<input type="email" id="email" name="email" required>
<!-- Submit button -->
<button type="submit">Sign Up</button>
<!-- Reset button -->
<button type="reset">Clear Form</button>
<!-- Regular button for JavaScript -->
<button type="button" onclick="alert('Clicked!')">
Learn More
</button>
<!-- Button outside form -->
<form id="my-form">
<input type="text" name="name">
</form>
<button type="submit" form="my-form">Submit External</button>
</form>
type="submit" — Submits the form
type="reset" — Clears all form fields
type="button" — Regular button for JavaScript
Here’s a realistic contact form:
Interactive code playground requires JavaScript. Here's the code:
<form action="/contact" method="POST">
<h2>Contact Us</h2>
<fieldset>
<legend>Personal Information</legend>
<label for="name">Full Name:</label>
<input type="text" id="name" name="name" required>
<label for="email">Email:</label>
<input type="email" id="email" name="email" required>
<label for="phone">Phone (optional):</label>
<input type="tel" id="phone" name="phone">
</fieldset>
<fieldset>
<legend>Your Message</legend>
<label for="subject">Subject:</label>
<select id="subject" name="subject" required>
<option value="">-- Select a subject --</option>
<option value="sales">Sales Inquiry</option>
<option value="support">Technical Support</option>
<option value="feedback">Feedback</option>
<option value="other">Other</option>
</select>
<label for="priority">Priority:</label>
<label>
<input type="radio" name="priority" value="low">
Low
</label>
<label>
<input type="radio" name="priority" value="high" checked>
High
</label>
<label for="message">Message:</label>
<textarea id="message" name="message" rows="5" required></textarea>
<label>
<input type="checkbox" name="newsletter" value="yes">
Subscribe to our newsletter
</label>
</fieldset>
<button type="submit">Send Message</button>
<button type="reset">Clear</button>
</form>
Every input needs a label connected with for:
< label for = " username " > Username: </ label >
< input id = " username " name = " username " >
< input name = " username " placeholder = " Username " >
Use <fieldset> and <legend> to group related fields:
< legend > Contact Methods </ legend >
< input type = " checkbox " name = " contact " value = " email " > Email
< input type = " checkbox " name = " contact " value = " phone " > Phone
Help users fix problems:
< label for = " password " > Password (minimum 8 characters): </ label >
< input type = " password " id = " password " name = " password " minlength = " 8 " required >
Create a form for a specific purpose:
Interactive code playground requires JavaScript. Here's the code:
<form action="/survey" method="POST">
<h2>Feedback Survey</h2>
<label for="name">Name:</label>
<input type="text" id="name" name="name" required>
<label for="experience">How would you rate your experience?</label>
<select id="experience" name="experience" required>
<option value="">-- Select --</option>
<option value="excellent">Excellent</option>
<option value="good">Good</option>
<option value="fair">Fair</option>
<option value="poor">Poor</option>
</select>
<label for="comments">Comments:</label>
<textarea id="comments" name="comments" rows="3"></textarea>
<label>
<input type="checkbox" name="contact" value="yes">
You may contact me
</label>
<button type="submit">Submit</button>
</form>
Using Placeholder as Label
Placeholders disappear when users type. Always use real <label> elements.
Not Using Proper Input Types
Use type="email" not type="text" for emails. Mobile users appreciate the correct keyboard.
Forgetting Method and Action
Always specify method and action so the form knows where to send data.
Use <form> with proper action and method attributes
Choose appropriate <input> types: text, email, number, date, file, etc.
Use <textarea> for longer text
Use <select> for dropdown choices
Use <button> for submissions and actions
Always use <label> elements connected to inputs
Use validation attributes: required, min, max, pattern
Use <fieldset> and <legend> to group related inputs
Test with keyboard and screen readers
Tables
Create accessible data tables with proper structure.
Continue →
Media
Embed audio, video, and responsive images.
Continue →