Forms are one of the most important parts of HTML because they allow users to send information to a website or application.
Examples:
An HTML form is a container that holds controls through which users enter or select data.
The main element is:
<form>
...
</form>For example:
<form>
<label>Name</label>
<input type="text">
<button type="submit">Submit</button>
</form>Visually:
┌─────────────────────────────┐
│ Name │
│ ┌─────────────────────────┐ │
│ │ Anubhav │ │
│ └─────────────────────────┘ │
│ │
│ [ Submit ] │
└─────────────────────────────┘The <form> itself doesn't create a visible input.
It provides the logical boundary and submission mechanism for the controls inside it.
A professional basic form looks like this:
<form action="/register" method="post">
<label for="name">Full Name</label>
<input type="text" id="name" name="name">
<button type="submit">Register</button>
</form>There are several important concepts here:
<form action="/register" method="post">Let's understand them one by one.
<form> Attributes#The two most important attributes are:
action
methodExample:
<form action="/login" method="post">action#action specifies where the form data should be submitted.
Example:
<form action="/login">When the user submits the form, the browser sends the data toward:
/loginAnother example:
<form action="/api/users">The destination could be a backend endpoint.
For example:
Browser
│
│ form submission
▼
/api/users
│
▼
Backend
│
▼
DatabaseIn a modern application, this could eventually reach:
HTML Form
↓
Next.js API route
↓
Server logic
↓
Databasemethod#method determines how the browser sends the form data.
The two primary methods are:
GET
POSTExample:
<form action="/search" method="get">or:
<form action="/register" method="post">GET generally means:
"I want to request something using these parameters."
Example:
<form action="/search" method="get">
<label for="query">Search</label>
<input
type="text"
id="query"
name="q"
>
<button type="submit">Search</button>
</form>Suppose the user enters:
kubernetesThe browser can produce a URL similar to:
/search?q=kubernetesThe data becomes part of the URL.
HTML:
<form action="/search" method="get">
<input
type="text"
name="q"
>
<button type="submit">
Search
</button>
</form>User enters:
HTML tutorialSubmission:
/search?q=HTML+tutorialConceptually:
Form
│
│ GET
▼
/search?q=HTML+tutorialThis is useful for things like:
POST is commonly used when submitting data that causes some processing or state change.
Example:
<form action="/register" method="post">
<label for="name">Name</label>
<input
type="text"
id="name"
name="name"
>
<button type="submit">
Register
</button>
</form>Conceptually:
Browser
│
│ POST
│
▼
/register
│
▼
ServerThe form fields are generally sent in the request body, rather than being appended to the URL as a query string.
| Feature | GET | POST |
|---|---|---|
| Typical purpose | Retrieve/query data | Submit/change data |
| Data commonly appears in URL | Yes | No |
| Bookmarkable result | Usually yes | Usually no |
| Good for search | ✅ | Sometimes |
| Good for registration | ❌ | ✅ |
| Good for login | Usually POST | ✅ |
| Good for creating records | ❌ | ✅ |
| Request body | Typically not used for form fields | Yes |
| Suitable for sensitive data | Not by itself | Not by itself |
Using POST does not automatically make data secure.
For secure transmission, use:
HTTPSnot merely:
POSTFor example:
HTTPS + POSTis appropriate for many sensitive form submissions.
<label> Element#<label> gives an input a human-readable description.
Bad:
<input type="text">Better:
<label for="name">Full Name</label>
<input
type="text"
id="name"
>The important connection is:
label for="name"
↓
input id="name"They must match.
Labels improve:
Screen readers can understand what the field represents.
Clicking the label can activate/focus the associated control.
For example:
<label for="email">Email Address</label>
<input
type="email"
id="email"
>Clicking:
Email Addressfocuses the input.
for + id#This is the most explicit approach.
<label for="email">Email</label>
<input
type="email"
id="email"
>Relationship:
for="email"
│
▼
id="email"You can also put the input inside the label:
<label>
Email
<input type="email">
</label>Both are valid.
The explicit approach is often easier to understand when building larger forms:
<label for="email">Email</label>
<input id="email" type="email"><input>#The <input> element is one of the most important HTML form elements.
Basic:
<input>Its behavior is determined primarily by:
type=""For example:
<input type="text"><input type="email"><input type="password"><input type="number"><label for="username">
Username
</label>
<input
type="text"
id="username"
name="username"
>This creates a normal text field.
Example:
Username
┌────────────────────────┐
│ anubhav │
└────────────────────────┘name — Extremely Important#One of the most important concepts in HTML forms is:
nameExample:
<input
type="text"
name="username"
>The name identifies the field in the submitted form data.
Consider:
<input
type="text"
name="username"
>User enters:
anubhavThe submitted data can conceptually be:
username=anubhavname Matters#Consider this:
<input
type="text"
id="username"
>There is no name.
The browser does not have a successful named form control to submit as:
username=...Now:
<input
type="text"
id="username"
name="username"
>The field can contribute:
username=anubhavid
↓
connects HTML elements / labels / CSS / JS
name
↓
identifies submitted form dataThis distinction is extremely important.
id vs name#| Attribute | Main purpose |
|---|---|
id |
Uniquely identifies an element in the document |
name |
Identifies the field in submitted form data |
for |
Associates a <label> with an element's id |
Example:
<label for="email">
Email
</label>
<input
type="email"
id="email"
name="email"
>Three concepts:
label
│
│ for="email"
▼
id="email"
name="email"
│
▼
submitted form datavalue#value represents the control's value.
Example:
<input
type="text"
name="country"
value="India"
>The initial value is:
IndiaFor some controls, value is especially important when the user submits the form.
Example:
<input
type="text"
name="username"
value="anubhav"
>Conceptually:
username=anubhavUse:
<input type="password">Example:
<label for="password">
Password
</label>
<input
type="password"
id="password"
name="password"
>The browser displays something like:
Password
┌────────────────────────┐
│ •••••••••• │
└────────────────────────┘type="password" primarily controls how the browser displays the input.
It does not encrypt the value.
Security still requires:
HTTPS
+
secure server-side handling
+
appropriate authentication/security practicesUse:
<input type="email">Example:
<label for="email">
Email
</label>
<input
type="email"
id="email"
name="email"
>Browsers can provide email-specific validation and mobile keyboards can provide an email-friendly layout.
However:
Client-side validation should not be treated as a security boundary.
The server should validate important data too.
<label for="age">
Age
</label>
<input
type="number"
id="age"
name="age"
>You can also specify constraints:
<input
type="number"
name="age"
min="18"
max="100"
>You can specify increments:
<input
type="number"
name="price"
min="0"
step="0.01"
><label for="website">
Website
</label>
<input
type="url"
id="website"
name="website"
>Example:
https://example.comBrowsers can perform URL-oriented validation.
Use:
<input type="tel">Example:
<label for="phone">
Phone Number
</label>
<input
type="tel"
id="phone"
name="phone"
>Important distinction:
teldoesn't guarantee a particular phone-number format.
Phone number formats vary between countries.
For stricter validation, use appropriate validation rules and server-side validation.
<label for="dob">
Date of Birth
</label>
<input
type="date"
id="dob"
name="dob"
>The browser can provide a date picker.
Example value:
2000-05-15<label for="appointment">
Appointment Time
</label>
<input
type="time"
id="appointment"
name="appointment"
>Example:
10:30You can create a submit button using:
<button type="submit">
Submit
</button>This is generally preferable to relying on an input for buttons because <button> is more flexible.
Example:
<form>
<input type="text" name="username">
<button type="submit">
Login
</button>
</form>Clicking the button submits the form.
<input type="submit">#Another option is:
<input
type="submit"
value="Submit"
>This works too.
But modern HTML commonly uses:
<button type="submit">
Submit
</button>because <button> can contain richer content.
You can create a reset button:
<button type="reset">
Reset
</button>It restores form controls to their initial values.
Example:
<form>
<input
type="text"
name="name"
>
<input
type="email"
name="email"
>
<button type="submit">
Submit
</button>
<button type="reset">
Reset
</button>
</form>Be careful with reset buttons in real applications.
Users can accidentally lose entered data.
Inside a form, explicitly specify the button type when appropriate.
<button type="submit">
Save
</button><button type="reset">
Reset
</button><button type="button">
Preview
</button>A plain:
<button>
Click
</button>inside a form generally behaves as a submit button.
Therefore, if it should not submit the form:
<button type="button">
Preview
</button>This is a very common interview and real-world issue.
placeholder#You can provide a hint:
<input
type="email"
placeholder="you@example.com"
>The user sees:
┌────────────────────────────┐
│ you@example.com │
└────────────────────────────┘But:
Placeholder is not a replacement for a label.
Bad:
<input
type="email"
placeholder="Enter your email"
>Better:
<label for="email">
Email Address
</label>
<input
type="email"
id="email"
name="email"
placeholder="you@example.com"
>Now the user has both:
Email Address
┌────────────────────────────┐
│ you@example.com │
└────────────────────────────┘Imagine the user types:
anubhav@example.comThe placeholder disappears.
Now the user may no longer know what the field represents.
A proper label remains visible.
Therefore:
Label = identifies the field
Placeholder = optional hint/examplerequired#You can make a field required:
<input
type="email"
name="email"
required
>The browser can prevent submission if the field doesn't satisfy the required constraint.
Example:
<label for="email">
Email *
</label>
<input
type="email"
id="email"
name="email"
required
>autocomplete#The autocomplete attribute helps the browser understand what kind of information the user is entering.
Example:
<input
type="text"
name="name"
autocomplete="name"
>Email:
<input
type="email"
name="email"
autocomplete="email"
>Password:
<input
type="password"
name="password"
autocomplete="current-password"
>New password:
<input
type="password"
name="password"
autocomplete="new-password"
>Phone:
<input
type="tel"
name="phone"
autocomplete="tel"
>Address:
<input
type="text"
name="address"
autocomplete="street-address"
>This improves:
Let's combine everything we've learned.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Registration</title>
</head>
<body>
<h1>Create Account</h1>
<form action="/register" method="post">
<div>
<label for="name">
Full Name
</label>
<input
type="text"
id="name"
name="name"
autocomplete="name"
required
>
</div>
<div>
<label for="email">
Email Address
</label>
<input
type="email"
id="email"
name="email"
autocomplete="email"
required
>
</div>
<div>
<label for="password">
Password
</label>
<input
type="password"
id="password"
name="password"
autocomplete="new-password"
required
>
</div>
<div>
<label for="age">
Age
</label>
<input
type="number"
id="age"
name="age"
min="18"
max="100"
>
</div>
<button type="submit">
Create Account
</button>
</form>
</body>
</html>Suppose the form contains:
<input
type="text"
name="name"
value="Anubhav"
>and:
<input
type="email"
name="email"
value="anubhav@example.com"
>Conceptually, the browser gathers the successful form controls:
name = Anubhav
email = anubhav@example.comFor GET, this can become:
/register?name=Anubhav&email=anubhav%40example.comFor POST, the data is normally sent in the request body.
The exact encoding depends on the form's enctype.
For ordinary forms, the default is:
application/x-www-form-urlencodedWe'll cover file uploads and multipart/form-data in a later chapter.
Think of a form like this:
USER
│
▼
┌────────────────┐
│ HTML Form │
│ │
│ Name │
│ Email │
│ Password │
└───────┬────────┘
│
▼
Browser validation
│
▼
Collect named fields
│
▼
Encode form data
│
▼
GET / POST request
│
▼
SERVER
│
▼
Process / Validate
│
▼
DatabaseNot every element inside a form necessarily contributes data.
The browser submits controls that are eligible for form submission.
For example:
<input
type="text"
name="username"
>has a name, so it can submit data.
But:
<input
type="text"
id="username"
>has no name, so it doesn't contribute a normal named form field.
This is why this is so important:
name="..."Consider:
<input
type="text"
name="username"
disabled
>A disabled form control generally isn't submitted.
This is different from:
readonlyExample:
<input
type="text"
name="username"
value="anubhav"
readonly
>A readonly text control can generally still contribute its value during submission.
So:
disabled
→ user can't interact
→ generally not submitted
readonly
→ user can't edit
→ can generally be submittedFor larger forms, organize fields logically.
Example:
<form action="/contact" method="post">
<h2>Contact Us</h2>
<div>
<label for="name">Name</label>
<input
type="text"
id="name"
name="name"
required
>
</div>
<div>
<label for="email">Email</label>
<input
type="email"
id="email"
name="email"
required
>
</div>
<div>
<label for="message">Message</label>
<textarea
id="message"
name="message"
></textarea>
</div>
<button type="submit">
Send Message
</button>
</form>We'll explore <textarea> properly in the next forms chapter.
<label>#<input type="text">Better:
<label for="name">Name</label>
<input id="name" type="text" name="name">name#Bad:
<input
type="email"
id="email"
>Better:
<input
type="email"
id="email"
name="email"
>Bad:
<input
type="text"
placeholder="Enter name"
>Better:
<label for="name">
Name
</label>
<input
type="text"
id="name"
name="name"
placeholder="Anubhav Chaudhary"
>type="text"#Bad:
<input type="text">
<input type="text">
<input type="text">Better:
<input type="email">
<input type="tel">
<input type="date">Choose the semantic input type that matches the data.
Bad assumption:
Browser says valid
↓
Therefore data is safeNo.
A malicious client can bypass browser validation.
Correct architecture:
Browser validation
+
Server validation
+
Server-side authorization
+
Secure transport| Type | Purpose |
|---|---|
text |
General text |
password |
Password entry |
email |
Email address |
number |
Numeric input |
url |
URL |
tel |
Telephone number |
date |
Date |
time |
Time |
datetime-local |
Local date + time |
month |
Month/year |
week |
Week/year |
search |
Search field |
submit |
Submit form |
reset |
Reset form |
button |
Generic button |
There are also specialized controls such as:
checkbox
radio
file
range
color
hiddenWe'll cover these in depth in the next chapter.
Create:
registration.htmlBuild this structure:
Create Account
Full Name
[________________]
Email
[________________]
Password
[________________]
Age
[________________]
Website
[________________]
Phone
[________________]
Date of Birth
[________________]
[ Create Account ] [ Reset ]Your HTML should include:
<form>and use:
<label>
<input>
<button>with:
id
name
type
required
autocompletewhere appropriate.
<form>?#It groups form controls and provides the mechanism for submitting their data.
action do?#It specifies the destination to which the form submission is sent.
GET commonly places form data in the URL query string, while POST normally sends form data in the request body.
name important?#name identifies a form control's submitted field name.
id and name?#id
→ identifies an element in the document
name
→ identifies submitted form data<label>?#For accessibility, usability, and proper association between descriptive text and form controls.
No.
Placeholder is a hint; a label identifies the field.
type="password" encrypt the password?#No.
It primarily masks the displayed input. Secure transmission requires HTTPS and secure backend handling.
name?#It generally won't contribute a named field to normal form submission.
disabled and readonly?#disabled
→ cannot interact
→ generally not submitted
readonly
→ cannot edit
→ can generally be submittedautocomplete used for?#It provides hints to the browser about the type of information expected so it can assist with autofill.
Because browser-side validation can be bypassed and cannot be trusted as a security boundary.
You now understand the foundation of HTML forms:
<form>
│
├── action
├── method
│
├── <label>
│
├── <input>
│ ├── text
│ ├── password
│ ├── email
│ ├── number
│ ├── url
│ ├── tel
│ ├── date
│ └── time
│
└── <button>
├── submit
├── reset
└── buttonAnd the most important relationships:
<label for="email">
↓
<input id="email">
<input name="email">
↓
submitted form dataThe key mental model is:
idconnects elements;nameconnects a control to submitted form data.
In the next chapter, we'll go deeper into the controls that make real-world forms powerful:
<select><option><textarea>fieldsetlegend<datalist>Mark it as complete to track your mastery.