HTML Forms
Sign-up pages, search boxes, feedback pages and checkout pages are all forms. A form is a part of the page that collects input from the user and sends it somewhere, usually to a server that stores it or answers it.
In this lesson you will learn how a form is built, why every input needs a label and a name, what the browser sends when the user clicks Submit, and how to choose between GET and POST.
How a form works
Every form follows the same three steps:
- The user fills in form controls: text boxes, checkboxes, drop-downs and so on.
- The user submits the form, usually by clicking a button or pressing Enter.
- The browser collects each control's name and value, and sends them to the URL in the form's
actionattribute, using the HTTP method in itsmethodattribute.
<form action="/register" method="post">
<!-- form controls go here -->
</form>actionis the URL that receives the data. If you leave it out, the data goes to the current page's URL.methodisgetorpost. If you leave it out, the browser usesget.
Forms cannot be nested: never put one <form> inside another.
Labels and inputs
The most common control is <input>, a single-line box. Every input needs a <label> that says what to type. Connect them by giving the input an id and the label a matching for attribute.
<label for="full-name">Full name</label>
<input id="full-name" name="full-name">
<!-- Or wrap the input inside the label -->
<label>
City
<input name="city">
</label>A proper label does two jobs. Screen readers read it aloud when the input gets focus, and clicking the label text moves focus into the input, which gives people on phones a bigger target to tap.
The name attribute decides what is sent
When the form is submitted, the browser sends one name=value pair for each control. The name comes from the control's name attribute and the value is what the user entered. A control without a name is not sent at all, which is a very common bug.
The example below has a short script that stops the real submission and shows you exactly what the browser would send instead. You do not need to understand the script yet; you will learn it in JavaScript Forms.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Feedback</title>
</head>
<body>
<h1>Canteen feedback</h1>
<form action="#" method="post">
<p>
<label for="student">Your name</label>
<input id="student" name="student">
</p>
<p>
<label for="dish">Favourite dish</label>
<input id="dish" name="dish">
</p>
<p>
<label for="note">Comment (not sent, no name)</label>
<input id="note">
</p>
<button>Send feedback</button>
</form>
<p>Data the browser would send: <output id="sent"></output></p>
<script>
const form = document.querySelector("form");
form.addEventListener("submit", (event) => {
event.preventDefault(); // demo only: stop the real submission
document.querySelector("#sent").textContent =
new URLSearchParams(new FormData(form)).toString();
});
</script>
</body>
</html>Type "Priya Sharma" and "Masala dosa", then submit. You will see student=Priya+Sharma&dish=Masala+dosa. Spaces become + and special characters are encoded so they can travel safely in a URL. The comment box is missing because it has no name.
GET or POST?
The method decides where the name=value pairs travel.
method="get" | method="post" | |
|---|---|---|
| Where the data goes | Added to the URL after a ? | Sent in the body of the request |
| Visible in the address bar | Yes | No |
| Can be bookmarked or shared | Yes | No |
| Good for | Search boxes, filters, sorting | Sign-ups, logins, orders, anything that changes data |
A GET search for trains might produce a URL such as /trains?from=Jaipur&to=Pune. That is perfect for a search, because the user can bookmark the results. It is terrible for a password, which would end up in the browser history and server logs.
Neither method encrypts anything. POST only keeps the data out of the URL. To protect data while it travels, the site must use HTTPS.
Buttons
A <button> inside a form has a type attribute with three possible values:
type="submit"submits the form. This is the default, so a plain<button>in a form is a submit button.type="button"does nothing on its own. Use it for buttons that run JavaScript, such as "Show password".type="reset"clears every field back to its starting value. Users press it by accident and lose their work, so it is rarely a good idea.
Pressing Enter inside a text input also submits the form, so short forms work smoothly from the keyboard.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Train Search</title>
</head>
<body>
<h1>Search trains</h1>
<form action="#" method="get">
<label for="from">From</label>
<input id="from" name="from" value="Jaipur">
<label for="to">To</label>
<input id="to" name="to">
<button type="button" id="swap">Swap</button>
<button type="submit">Search</button>
</form>
<p>A GET form would load: <output id="url"></output></p>
<script>
const form = document.querySelector("form");
document.querySelector("#swap").addEventListener("click", () => {
[form.from.value, form.to.value] = [form.to.value, form.from.value];
});
form.addEventListener("submit", (event) => {
event.preventDefault(); // demo only
document.querySelector("#url").textContent =
"/trains?" + new URLSearchParams(new FormData(form));
});
</script>
</body>
</html>The Swap button has type="button", so it swaps the two cities without submitting. Try removing type="button" from it: now clicking Swap submits the form too.
Where does the data go?
HTML only builds the form and sends the data. Something on the server must receive it, check it and store it. In this course, examples use action="#" and a small script so nothing is sent anywhere real. When you are ready, PHP Form Handling shows how a server reads the values, and Input Types shows the many kinds of input you can collect.
Common mistakes
- Missing
nameattributes. The field looks fine but its value never reaches the server. forandidthat do not match. The label is no longer connected, so clicking it does nothing and screen readers stay silent.- Using GET for private data. Passwords and personal details must use POST over HTTPS.
- A plain
<button>that should not submit. Addtype="button"to buttons that only run JavaScript.
Key points
- A
<form>sends name=value pairs to the URL inactionusing the method inmethod. - Connect every input to a visible
<label>with matchingforandidattributes. - Only controls with a
nameattribute are sent. - Use GET for searches and filters, POST for anything private or that changes data, and HTTPS for both.
- A
<button>in a form submits by default; usetype="button"for script-only buttons.
Exercise
Create a newsletter sign-up form that uses POST. It needs a labelled input for the subscriber's name and one for their city, and a submit button that says "Subscribe". Add the demo script from this lesson so that submitting shows the data the browser would send. Make sure both values appear.
Show solution
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Newsletter</title>
</head>
<body>
<form action="#" method="post">
<p>
<label for="sub-name">Name</label>
<input id="sub-name" name="name">
</p>
<p>
<label for="sub-city">City</label>
<input id="sub-city" name="city">
</p>
<button type="submit">Subscribe</button>
</form>
<p>Would send: <output id="sent"></output></p>
<script>
const form = document.querySelector("form");
form.addEventListener("submit", (event) => {
event.preventDefault();
document.querySelector("#sent").textContent =
new URLSearchParams(new FormData(form)).toString();
});
</script>
</body>
</html>Both inputs have a name, so both appear in the output, for example name=Meera&city=Lucknow.
Quick Quiz
1. Which attribute decides the name in each name=value pair that a form sends?
Only the name attribute is used when the browser builds the submitted data.
2. What is the default type of a <button> inside a form?
A plain <button> in a form submits it, which is why script-only buttons need type="button".
3. Which method should a login form use?
GET puts data in the URL, history and logs; POST keeps it in the request body (and HTTPS encrypts it).
4. Why is a placeholder not enough instead of a label?
Placeholders vanish when the user types, so a visible label is still needed.
Learn HTML with a mentor
Free lessons get you started. Our Full Stack Web Development training adds real projects and code reviews from working developers.
- Project-based learning
- Mentor code reviews
- Free counselling call
