HTML Forms
Everything you have built so far is one-way: you publish, and visitors read. Forms turn the web into a conversation. They are how a visitor signs up, logs in, searches, orders a book, leaves a comment, books a seat, or tells you what they think. Nearly every useful website has at least one.
Forms are also where HTML meets the real world. People make typos, use screen readers, type on small phones, speak different languages, and sometimes try to break things on purpose. A good form handles all of that gracefully. This section teaches you how to build forms that are clear, easy to complete, accessible to everyone, and safe.
What You Will Learnβ
In this section, you will be able to:
- Build a form with the
<form>element and decide where its data goes - Choose between the GET and POST methods
- Create fields with
<input>and name them with<label> - Pick the right input type for emails, numbers, dates, passwords, files, and more
- Collect longer text with
<textarea>and choices with<select>,<option>, and<datalist> - Add buttons and group related fields with
<fieldset>and<legend> - Help users with
autocomplete - Check data in the browser with
required,min,max,minlength,maxlength, andpattern - Send files with multipart form data
- Make forms accessible and secure
You should be comfortable with basic HTML elements and attributes. If you need a refresher, read Table Basics for a sense of how structured elements fit together, and Links and Navigation for how URLs work, since forms send data to a URL.
Your First Formβ
Here is a small sign-up form. Try typing in the demo. (Its submit button is switched off on this page, so nothing is sent anywhere.)
- HTML Code
- Browser Output
<form action="/subscribe" method="post">
<p>
<label for="name">Your name</label><br />
<input type="text" id="name" name="name" required />
</p>
<p>
<label for="email">Email address</label><br />
<input type="email" id="email" name="email" required />
</p>
<p>
<label for="level">Your level</label><br />
<select id="level" name="level">
<option value="beginner">Beginner</option>
<option value="intermediate">Intermediate</option>
</select>
</p>
<p>
<label>
<input type="checkbox" name="news" />
Send me weekly tips
</label>
</p>
<button type="submit">Subscribe</button>
</form>
Even this small form uses most of what you will learn. Click Subscribe with empty fields, and your browser will check them for you, with no JavaScript needed.
How a Form Worksβ
A form is a round trip:
1. The visitor fills in the fields
β
βΌ
2. The browser checks the data (required, type, pattern, min, max ...)
β problems? β the visitor fixes them
βΌ
3. The visitor presses Submit
β
βΌ
4. The browser packs the data into name=value pairs
and sends them to the address in action using the method
β
βΌ
5. A server receives, checks again, and acts (saves, replies, redirects)
β
βΌ
6. The visitor sees a result page or message
Two important points sit in that picture:
- HTML creates the form and does the first check (step 2). It does not store or process anything by itself. A server does that (step 5), written in a language such as Node.js, Python, PHP, or Java.
- The browser's check is a convenience, not security. Anyone can bypass it. The server must always check again. You will learn why in Secure Form Design.
The Parts of a Formβ
| Part | Element | What it does |
|---|---|---|
| The container | <form> | Wraps the fields, and says where and how to send them |
| A field | <input>, <textarea>, <select> | Where the visitor types or chooses |
| A name tag | <label> | Tells people (and tools) what a field is for |
| A group | <fieldset> and <legend> | Groups related fields under a title |
| An action | <button> | Submits, resets, or runs something |
| A helper | <datalist> | Suggests values while typing |
The Two Attributes Every Field Needsβ
Almost every field depends on two attributes. If you remember nothing else, remember these:
| Attribute | Used for | What happens without it |
|---|---|---|
name | The key under which the field's value is sent to the server | The value is not sent at all |
id | Linking a <label> to the field with for | The label is not connected, which breaks accessibility and click-to-focus |
<label for="email">Email</label>
<input type="email" id="email" name="email" />
When the form is submitted, the browser sends email=ada@example.com. The name is the key, and what the visitor typed is the value.
The Form Controls at a Glanceβ
| You need... | Use | Lesson |
|---|---|---|
| A short line of text | <input type="text"> | Input Element |
| An email, number, date, color, file... | <input type="email">, number, date, and more | Input Types |
| A long message | <textarea> | Textarea |
| One choice from a list | <select> with <option> | Select, Option and Optgroup |
| A text field with suggestions | <input list> with <datalist> | Datalist |
| One choice from a few, all visible | <input type="radio"> | Input Types |
| A yes/no or several choices | <input type="checkbox"> | Input Types |
| A button to send or act | <button> | Button |
Choosing the Right Controlβ
Picking the right control saves visitors effort, and often prevents mistakes before they happen.
| Situation | Best control | Why |
|---|---|---|
| 2 to 5 options, only one allowed | Radio buttons | All options are visible at once |
| 6 to about 15 options, only one allowed | <select> | Saves space |
| Many options, or the user may know the answer already | Text input with <datalist> | Suggestions plus free typing |
| Several options allowed | Checkboxes | Clear and simple |
| Agree or not | A single checkbox | The standard pattern |
| A short answer | <input> | One line |
| A comment, message, or address | <textarea> | Room to write |
Your Learning Pathβ
The lessons are grouped in the order that builds a form from the outside in. Follow them in order.
ποΈ Form Element
Learn the HTML form element: what it does, how browsers collect and send name and value pairs, the main attributes (action, method, enctype, target, autocomplete, novalidate), submitting with buttons and the Enter key, search forms, the form attribute, accessibility, and common mistakes on CodeHarborHub.
ποΈ Label Element
Learn the HTML label element: how to name every form field with for and id, wrap controls inside labels, why placeholders are not labels, how labels improve clicking and screen reader support, visually hidden labels, hints and required markers, and common mistakes on CodeHarborHub.
ποΈ Input Element
Learn the HTML input element: the void element behind most form fields. Understand type, name, id, value, placeholder, required, disabled versus readonly, autofocus, size, inputmode, and other key attributes, how values are sent, and common mistakes with live examples on CodeHarborHub.
ποΈ Input Types
19 items
ποΈ Textarea
Learn the HTML textarea element for multi-line text: rows and cols, the starting text between the tags, maxlength and minlength, a live character counter, auto-growing height, wrap, resize, how line breaks are sent, showing user text safely, accessibility, and common mistakes on CodeHarborHub.
ποΈ Select
Learn the HTML select element for dropdown lists: building a dropdown with option, the placeholder option pattern with required, what is sent, multiple selection and the size attribute, change events, dependent dropdowns, keyboard use, styling limits, accessibility, and common mistakes on CodeHarborHub.
ποΈ Option and Optgroup
Learn the HTML option and optgroup elements: the value, selected, disabled, and label attributes, how text and value differ, grouping long lists with optgroup, disabled options and groups, how the default choice is picked, adding and removing options with JavaScript, accessibility, and common mistakes on CodeHarborHub.
ποΈ Datalist
Learn the HTML datalist element for suggestions: connecting an input with the list attribute, suggestions versus restrictions, option value and label, using datalist with search, email, number, range, and color inputs, limiting input to the list with JavaScript, loading suggestions dynamically, accessibility limits, and common mistakes on CodeHarborHub.
ποΈ Button
Learn the HTML button element: the type attribute (submit, reset, button) and why submit is the default, stable name and value for multiple actions, icons and rich content inside a button, toggle buttons with aria-pressed, disabled versus aria-disabled, loading states, button versus link, styling, accessibility, and common mistakes on CodeHarborHub.
ποΈ Fieldset and Legend
Learn the HTML fieldset and legend elements: grouping related form controls, naming a group for screen readers, radio and checkbox groups, split date fields, address blocks, disabling a whole group with the disabled attribute, styling the border and legend, nesting rules, and common mistakes on CodeHarborHub.
ποΈ Form Validation
Learn HTML form validation: the built-in constraint validation attributes, the ValidityState flags, checkValidity, reportValidity, and setCustomValidity, the :valid, :invalid, and :user-invalid CSS pseudo-classes, novalidate, writing friendly accessible error messages with aria-invalid and an error summary, and why the server must always validate again.
ποΈ Required
Learn the HTML required attribute: which form controls support it, how it behaves for text, checkboxes, radio groups, selects, and files, the :required and :optional CSS pseudo-classes, how to mark required fields accessibly with aria-required and clear labels, whitespace-only values, and why the server must still check for missing data.
ποΈ Pattern
Learn the HTML pattern attribute: how regular expressions validate text fields, which input types support it, the implicit anchoring rule, writing helpful title messages, common patterns for codes and usernames, why strict patterns for names and phone numbers fail global visitors, the patternMismatch validity flag, and why the server must validate again.
ποΈ Minlength and Maxlength
Learn the HTML minlength and maxlength attributes: setting minimum and maximum text lengths on inputs and textareas, how browsers count characters (UTF-16 code units, emoji, and line breaks), the tooShort and tooLong validity flags, accessible character counters, sensible limits for passwords and names, and why the server must enforce limits too.
ποΈ Min and Max
Learn the HTML min, max, and step attributes: limiting numbers, ranges, dates, times, months, and weeks, how the step base works, the rangeUnderflow, rangeOverflow, and stepMismatch validity flags, setting today as a minimum date, linking two date fields, money and decimal pitfalls, and why the server must check ranges again.
ποΈ Autocomplete
Learn the HTML autocomplete attribute: helping browsers and password managers fill in names, emails, addresses, phone numbers, and payment details, the most useful autocomplete tokens, shipping and billing sections, current-password, new-password, and one-time-code, when autocomplete off is appropriate, accessibility benefits (WCAG 1.3.5), and security and privacy notes.
ποΈ Form Methods
Learn the HTML form method attribute: how GET puts data in the URL and POST sends it in the request body, when to use each one, URL encoding, the post-redirect-get pattern, method dialog, why HTML forms cannot send PUT or DELETE, CSRF and privacy notes, and how to choose the safe method for search, login, and checkout forms.
ποΈ Form Action
Learn the HTML form action attribute: where a form sends its data, absolute and relative URLs, what happens when action is left out, the GET query string trap, formaction on buttons, the target attribute, third-party form services, mailto actions, progressive enhancement with fetch, and security notes on HTTPS, CSRF, and the Content-Security-Policy form-action rule.
ποΈ Multipart Form Data
Learn the HTML form enctype attribute: application/x-www-form-urlencoded, multipart/form-data, and text/plain, why file uploads need multipart, what a multipart request body looks like, using FormData with fetch without setting the Content-Type, formenctype on buttons, and safe server-side handling of uploaded files, size limits, and filenames.
ποΈ Accessible Forms
Learn how to build accessible HTML forms: visible labels, grouping with fieldset and legend, hints and instructions, marking required fields, clear error messages with aria-invalid and aria-describedby, autocomplete, keyboard and focus, touch target size, WCAG 2.2 rules for forms, redundant entry and accessible authentication, and a practical testing checklist.
ποΈ Secure Form Design
Learn secure HTML form design: never trusting the browser, server-side validation with allow-lists, HTTPS, escaping output to stop XSS, parameterised queries against SQL injection, CSRF tokens and SameSite cookies, safe password handling, rate limiting and bot defences, avoiding information leaks, safe file uploads, mass assignment, privacy and data minimisation, and a practical security checklist.
This section adds two lessons that were not in the original plan: Disabled and Readonly (disabled-and-readonly.mdx) and Styling Forms (form-styling.mdx). Both are everyday needs that do not fit neatly into another lesson. Fields often need to be shown but not edited, and the default form controls look quite plain.
What Makes a Good Form?β
Think of it as a short conversation with a stranger. You want it to be polite, quick, and clear.
- Ask only what you need. Every extra field makes people leave.
- Label every field, visibly and correctly.
- Use the right control, so the phone shows the right keyboard.
- Help before correcting. Show format hints, and use
autocomplete. - Validate kindly. Say what is wrong and how to fix it, in plain words.
- Work with a keyboard alone, and with a screen reader.
- Work on a small screen, with big enough touch targets.
- Keep it safe. Check everything again on the server, and protect personal data.
- Confirm success. Tell people clearly that their message was received.
Common Beginner Mistakesβ
| Mistake | What goes wrong | Where you will fix it |
|---|---|---|
Fields with no name | Their data is never sent | Input Element |
| Using the placeholder as the label | The hint vanishes when typing, and screen readers may skip it | Label Element |
| Clicking a label does nothing | for and id do not match | Label Element |
Using type="text" for everything | No helpful keyboard, no free validation | Input Types |
| Using GET for passwords | They appear in the address bar and logs | Form Methods |
A <button> inside a form that submits by accident | Missing type="button" | Button |
| Unclear error messages | People give up | Form Validation |
| Relying only on browser checks | Anyone can bypass them | Secure Form Design |
No enctype on a file upload | Only the file's name is sent | Multipart Form Data |
| Using red color alone to show errors | Colorblind users cannot tell | Accessible Forms |
Forms for a Global Audienceβ
People everywhere will use your form. Small decisions decide whether it works for them.
- Names are not "first" and "last." Many people have one name, several family names, or a different order. A single "Full name" field is often kinder, and avoid forcing a pattern.
- Addresses differ. Not every country has states or ZIP codes. Allow flexible fields, and do not require a field that may not exist.
- Phone numbers vary. Allow a country code, spaces, and dashes. Do not reject a valid format.
- Dates and numbers vary.
<input type="date">lets the browser show the person's own format. Be careful withpatternrules built for one country. - Use
autocompletetokens, so browsers fill in details in the person's language. - Allow longer text. Names and addresses in some languages are longer than you expect, and may include accents and non-Latin characters.
- Set
langon the page, and write labels and messages in plain, short words that translate well. - Mind data laws. Rules about collecting personal data (such as GDPR in Europe) apply to visitors from those regions. Collect the minimum, say why, and let people ask for deletion.
A Note on Security Before You Startβ
Every field you add is a door into your system. People on the internet will try the handle. As you work through this section, keep three rules in mind:
- Never trust data from the browser. Always validate and clean it on the server.
- Use POST (over HTTPS) for anything private, and never send passwords by GET.
- Collect only what you need, and protect it.
You will study each of these in depth in Form Methods and Secure Form Design.
Quick Recapβ
Test yourself. Click a question to reveal the answer.
1. Which element wraps all the fields of a form?
The <form> element. Its action says where to send the data, and its method says how.
2. Which attribute decides the key under which a field's value is sent?
name. A field with no name is not sent at all.
3. Which two attributes connect a label to its field?
for on the <label> must match id on the field. You can also wrap the field inside the <label>.
4. Does HTML store the data that visitors submit?
No. HTML only builds the form and sends the data. A server-side program receives, checks, and stores it.
5. Why must a server check the data again, even if the browser already did?
Browser checks are a convenience, and anyone can bypass them. The server is the only place where checks can be trusted.
6. When would you pick radio buttons over a select list?
When there are only a few options (about two to five) and only one may be chosen, so everything is visible at once.
Key Takeawaysβ
- A form is a conversation: fields collect data, the browser does a first check, and a server does the real work.
<form>holds the fields.actionandmethoddecide where and how the data is sent.- Give every field a
name(so it is sent) and a matching<label>(so it is understood). - Pick the right control and input type, and use
required,min,max,minlength,maxlength, andpatternto guide people. - Build for everyone: keyboard, screen reader, small screen, and any language or region.
- Never trust the browser. Check on the server, use POST over HTTPS for private data, and collect only what you need.
Ready to begin? Start with Form Element.