HTML Forms Basics: form, input, label and button Explained
Learn HTML forms from the ground up: the form element, action and method, input and name, connecting label to input, button types, and a full example.
What you will learn
Every time you log in, search, sign up, or send a message on the web, you’re using an HTML form. In this lesson you will learn the <form> element, how it decides where and how to send data with action and method, the <input> element and why name is the attribute that makes everything actually work, how to properly connect a <label> to its input, and the different jobs a <button> can do.
The <form> element
<form action="/submit-contact" method="post">
<!-- inputs go here -->
</form>
<form> is a container for everything the visitor will fill in and submit together — text fields, checkboxes, buttons. Two attributes control what happens when it’s submitted:
action— the URL the form’s data is sent to. If left out, the form submits to the current page’s own URL.method— how the data is sent. The two common values:
method |
Behaviour |
|---|---|
get |
Appends the form data to the URL as a query string (?name=Aman&email=...), visible in the address bar. Good for searches and filters — things you’d want to bookmark or share as a link. |
post |
Sends the data in the request body, not visible in the URL. Used for anything that changes data or is sensitive — sign-ups, passwords, messages. |
Rule of thumb: use get for search/filter forms where the result should be shareable as a URL. Use post for everything that submits or changes data, especially anything with a password or personal information.
Submitting a form is normally the job of a backend server, which you haven’t built yet at this stage of the course. For now,
actioncan point anywhere — the important thing is learning the HTML structure correctly. You’ll wire forms up to real servers, or to JavaScript, later in the course.
<input>: the basic building block
<input type="text" name="fullName">
<input> is a void element (no closing tag) that creates a form control. Its type attribute decides what kind of control it becomes — text for a plain text box, but there are many more types, which get their own dedicated lesson right after this one.
name: the attribute that makes a form actually work
This is the single most important — and most forgotten — attribute in a form. When a form is submitted, only fields with a name are actually sent. The name becomes the key, and whatever the visitor typed becomes the value:
<input type="text" name="fullName" value="">
<!-- submitted as: fullName=Aman+Sharma -->
<!-- Wrong: this input has no name, so its value is silently dropped on submit -->
<input type="text" placeholder="Your name">
Every input that should be submitted needs a name. It’s easy to forget because the input still looks and works fine on screen — the mistake only shows up once you check what data actually arrived at the server.
<label>: connecting text to its input
<label for="email">Email address</label>
<input type="email" id="email" name="email">
A <label> is not just descriptive text sitting near an input — it should be programmatically connected to it. There are two correct ways to do this:
Method 1: for and id (most common, most flexible)
<label for="email">Email address</label>
<input type="email" id="email" name="email">
The label’s for value must exactly match the input’s id value.
Method 2: wrap the input inside the label
<label>
Email address
<input type="email" name="email">
</label>
Here no for/id pair is needed — the wrapping itself creates the connection.
Why this connection matters
- Clicking the label text focuses (or checks) the input. Try it in the practice editor — click the words “Full name”, and the text box gets focus. This is a huge, often-overlooked usability win, especially for checkboxes and radio buttons, which are small and hard to tap precisely on a phone.
- Screen readers announce the label when the input receives focus. Without a real
<label>, a screen reader user hears only “edit text, blank” — no idea what to type.
<!-- Wrong: looks fine visually, but is not actually connected -->
<span>Email address</span>
<input type="email" name="email">
<!-- Right -->
<label for="email">Email address</label>
<input type="email" id="email" name="email">
placeholder is not a replacement for label
<!-- Wrong: no real label, only a placeholder -->
<input type="text" name="fullName" placeholder="Full name">
placeholder shows faint hint text inside the box, but it disappears the moment the visitor starts typing, and screen readers do not reliably treat it as a label. Always pair a real <label> with an input; use placeholder only for an extra example or format hint (placeholder="e.g. 9876543210"), never as the only description of the field.
<button>: three different jobs
<button type="submit">Send</button>
<button type="reset">Clear form</button>
<button type="button">Show preview</button>
type |
What it does |
|---|---|
submit |
Submits the form. This is the default if you don’t set type at all. |
reset |
Clears all fields in the form back to their original values. |
button |
Does nothing by itself — used when you want a button that only runs JavaScript (like toggling something), with no form-submitting side effect. |
A very common accidental bug: any
<button>inside a<form>with notypeset defaults totype="submit". If you add a button meant only to run some JavaScript (say, “Show password”) and forget to settype="button", clicking it will unexpectedly submit the whole form. Always settypeexplicitly on every button inside a form.
You can also use <input type="submit" value="Send">, which is the older way of writing a submit button — <button> is generally preferred today because it can contain HTML content (like an icon) inside it, not just plain text.
A complete, correct example
<form action="/contact" method="post">
<label for="name">Full name</label>
<input type="text" id="name" name="fullName" placeholder="e.g. Aman Sharma" required>
<label for="email">Email</label>
<input type="email" id="email" name="email" placeholder="you@example.com" required>
<label for="message">Message</label>
<textarea id="message" name="message" rows="4"></textarea>
<button type="submit">Send message</button>
<button type="reset">Clear</button>
</form>
(required and <textarea> are covered in their own upcoming lessons — this example just shows how the pieces you’ve learned here fit together with what’s coming next.)
Common mistakes
- Forgetting
nameon an input. It will look completely normal but its value never gets submitted. - Using a
<span>or plain text instead of a real<label>. You lose the click-to-focus behaviour and screen reader support. - Mismatched
for/id— even a small typo means the label silently isn’t connected to anything. - Relying on
placeholderalone, with no real<label>. - Forgetting
type="button"on a button that should only trigger JavaScript, causing an accidental form submission. - Choosing
method="get"for sensitive data, like a password — it ends up visible in the URL and browser history. - Nesting a
<form>inside another<form>. This is invalid HTML; forms cannot be nested.
Interview-style questions
Why is the name attribute important on a form input?
Only fields with a name are included when the form is submitted; the name becomes the key for that field’s submitted value.
What is the difference between method="get" and method="post"?
get sends form data as part of the URL, suitable for searches and shareable results. post sends it in the request body, used for anything sensitive or that changes data.
Why should you use <label> instead of just placing text near an input?
A real <label> is programmatically linked to its input, letting a click on the label focus the field and letting screen readers announce it — plain text next to an input provides neither.
What happens if a <button> inside a form has no type attribute?
It defaults to type="submit", so clicking it submits the form — a common source of accidental submissions when a button was only meant to trigger JavaScript.
Practice
-
Use the Practice in Editor button. Click directly on the label text “Full name” and notice the input receives focus.
-
Remove the
nameattribute from the email input, imagine submitting the form, and explain what would happen to that field’s data. -
Add a third
<button type="button">Preview</button>to the form and explain whytype="button"is necessary here rather than leaving the default. -
Fix this code (it has two mistakes: a label not connected to its input, and a button that will accidentally submit the form):
<form action="/search" method="get"> <span>Search term</span> <input type="text" name="q"> <button>Show advanced options</button> </form>
Recap
<form>wraps a set of fields;actionsets where data is sent,method(getorpost) sets how.- Every input that should be submitted needs a
name— without it, its value is silently dropped. - Connect every
<label>to its input with matchingfor/id, or by wrapping the input inside the label. placeholderis a hint inside the box, not a substitute for a real<label>.<button>defaults totype="submit"inside a form — always settype="button"explicitly for buttons that shouldn’t submit.