HTML Forms and Inputs: A Complete Beginner's Guide
Forms are how the web collects information. This guide covers every part of an HTML form — the form element, input types, labels, validation, and submission — so you can build forms users can actually use.
What you'll learn
- ✓How the <form> element groups inputs and where data is sent
- ✓The most useful <input> types and when to pick each one
- ✓Why labels matter and how to wire them up correctly
- ✓How <textarea>, <select>, and <button> fit into a form
- ✓Built-in validation attributes that catch mistakes before JavaScript runs
- ✓What the name attribute does and how submission actually works
Prerequisites
- •Comfort with basic HTML tags — see Essential HTML Tags
Forms are the single most important interface on the web. Every sign-up screen, search box, checkout flow, and contact page is built from the same handful of HTML elements. Once you understand how they fit together, you can build any form you will ever need.
This post is a guided tour of HTML forms — from the wrapping <form> element down to the smallest validation attribute.
What a form actually is
A form is a container that groups together a set of inputs and a button that submits them. When the user clicks the submit button, the browser collects the values, packages them up, and sends them to a server.
<form action="/signup" method="post">
<label for="email">Email</label>
<input type="email" id="email" name="email" required />
<button type="submit">Sign up</button>
</form>
Two attributes on the <form> tag do the heavy lifting:
action— the URL the data will be sent to.method— how the data is sent.getputs values in the URL (good for searches),postputs them in the request body (good for everything else, especially passwords).
If you omit action, the form submits to the current page. If you omit method, the default is get. Always set both deliberately.
The <input> element
<input> is the workhorse of every form. The same tag becomes a text box, a password field, a checkbox, or a date picker depending on the type attribute.
<input type="text" name="username" />
<input type="email" name="email" />
<input type="password" name="password" />
<input type="number" name="age" />
<input type="date" name="dob" />
<input type="checkbox" name="newsletter" />
<input type="radio" name="plan" value="free" />
<input type="file" name="avatar" />
<input type="url" name="website" />
<input type="tel" name="phone" />
<input type="search" name="q" />
<input type="hidden" name="csrf" value="abc123" />
Each type changes more than the appearance. type="email" shows an email keyboard on mobile and validates the format. type="number" shows a numeric keyboard and rejects letters. type="date" opens a calendar picker. Pick the most specific type that fits your data and the browser does the rest of the work for you.
Labels and why they matter
Every input needs a label. A label describes what the user is supposed to type and — crucially — makes the form usable for people who rely on screen readers or have trouble tapping small targets.
There are two ways to connect a label to an input. Wire them up by id:
<label for="email">Email address</label>
<input type="email" id="email" name="email" />
Or wrap the input inside the label:
<label>
Email address
<input type="email" name="email" />
</label>
Both work. The for/id version is more flexible because the two pieces can sit anywhere in the DOM. Whatever you pick, never leave an input unlabeled. Placeholder text is not a label — it disappears the moment the user starts typing.
Try it yourself. Build a tiny form with one labeled text input and a submit button. Click the label text. The browser should focus the input automatically. If it does, the connection works.
The name attribute
The single most-forgotten attribute on an input is name. Without it, the value never gets submitted at all. The browser packages each input as name=value when the form is sent.
<form action="/login" method="post">
<input type="text" name="username" />
<input type="password" name="password" />
<button type="submit">Log in</button>
</form>
When the user submits, the server receives username=ada&password=hunter2. No name, no data. If a field is not showing up on the server, the missing name is almost always the cause.
Multi-line input with <textarea>
For longer text — comments, bios, messages — use <textarea>:
<label for="bio">Tell us about yourself</label>
<textarea id="bio" name="bio" rows="5" cols="40"></textarea>
rows sets the visible height in lines; cols sets the visible width in characters. Both can be overridden with CSS. Unlike <input>, <textarea> is not a void element — it has a separate closing tag, and any content between the tags becomes the initial value.
Dropdowns with <select>
A <select> element creates a dropdown of choices:
<label for="country">Country</label>
<select id="country" name="country">
<option value="">Choose one</option>
<option value="us">United States</option>
<option value="uk">United Kingdom</option>
<option value="in">India</option>
</select>
The value of each <option> is what gets submitted; the text between the tags is what the user sees. Add multiple to allow more than one selection, and group related options with <optgroup>:
<select name="role" multiple>
<optgroup label="Engineering">
<option value="frontend">Frontend</option>
<option value="backend">Backend</option>
</optgroup>
<optgroup label="Design">
<option value="ux">UX</option>
<option value="visual">Visual</option>
</optgroup>
</select>
Buttons
A form needs at least one button to submit it. The <button> element has three types:
<button type="submit">Save</button>
<button type="reset">Clear the form</button>
<button type="button">Run some JavaScript</button>
submitis the default. Clicking it submits the form.resetclears every input back to its initial value. Use sparingly — users hit it by accident.buttondoes nothing on its own and is meant to be wired up with JavaScript.
You can also style <button> freely because, unlike <input type="submit">, it accepts child HTML — icons, spans, anything.
Built-in validation
Modern browsers ship with form validation that runs before any of your JavaScript. The attributes you will use most:
<!-- Field must be filled in -->
<input type="text" name="username" required />
<!-- Minimum and maximum number of characters -->
<input type="text" name="title" minlength="3" maxlength="80" />
<!-- Numeric range -->
<input type="number" name="age" min="18" max="120" />
<!-- Regex pattern -->
<input
type="text"
name="zip"
pattern="\d{5}"
title="Five digits"
/>
<!-- Type-based validation -->
<input type="email" name="email" />
<input type="url" name="website" />
When the user submits, the browser checks every constraint. If anything fails, submission is blocked and the offending field is highlighted with a native tooltip. You get this for free — no script required.
required is the one you will use on almost every meaningful field. pattern is powerful but only fires when the field has content; combine it with required if you need both.
A complete example
A realistic contact form using everything above:
<form action="/contact" method="post">
<label for="name">Your name</label>
<input
type="text"
id="name"
name="name"
required
minlength="2"
maxlength="60"
/>
<label for="email">Email</label>
<input type="email" id="email" name="email" required />
<label for="topic">What is this about?</label>
<select id="topic" name="topic" required>
<option value="">Choose a topic</option>
<option value="support">Support</option>
<option value="sales">Sales</option>
<option value="other">Something else</option>
</select>
<label for="message">Message</label>
<textarea
id="message"
name="message"
rows="5"
required
minlength="10"
></textarea>
<label>
<input type="checkbox" name="subscribe" />
Subscribe to the newsletter
</label>
<button type="submit">Send message</button>
</form>
Read the markup top to bottom. Every input has a label, every input has a name, and the inputs that matter have required plus a reasonable constraint. That is what a healthy form looks like.
Try it yourself. Save the contact form above as a file and open it in a browser. Try submitting it empty. Try entering “ab” in the name field. Try entering “notanemail” in the email field. The browser stops you every time, and you have not written a single line of JavaScript.
How submission actually works
When the user clicks submit:
- The browser walks the form and collects every input that has a
name. - It runs the built-in validation. If anything fails, submission stops.
- It encodes the values according to the
methodattribute. - It sends a request to the
actionURL. - The page navigates to whatever the server responds with.
For richer behavior — submitting without a page reload, showing custom errors, or sending JSON — you intercept the form with JavaScript using the submit event. That is the next step beyond this post. But the HTML you have just learned is the foundation every JavaScript-driven form is built on top of.
A few practical tips
- Label every input. No exceptions.
- Always set
nameon any field whose value matters. - Pick the most specific
typefor the data —email,tel,number,date— to get free validation and the right mobile keyboard. - Use
requiredinstead of writing your own check in JavaScript. - Group related inputs with
<fieldset>and<legend>when forms get long. - Test by tabbing through the form with the keyboard. If you cannot reach every control with Tab, neither can many of your users.
Recap
You now know:
- A
<form>sends grouped input values to theactionURL using themethodyou set - The
<input>element has manytypevalues that change both UI and validation - Every input needs a
<label>and aname— labels for usability, names for submission <textarea>,<select>, and<button>cover the cases<input>does notrequired,minlength,maxlength,min,max, andpatterngive you free validation- The browser does most of the work; JavaScript is only needed for the fancier bits
Next steps
A form is structurally complete the moment the HTML is right, but a real form also needs to be readable and accessible. The next step is understanding semantic HTML — why the right tag in the right place matters for everyone who visits your page.
Next: Semantic HTML: Why Tags Have Meaning
Questions or feedback? Email codeloomdevv@gmail.com.