HTML Reference
<form> — The Form Element
The container that turns static HTML into an interactive page. Collects user input and sends it to a server.
Last updated: October 2026
Definition: The <form> element wraps interactive controls (inputs, buttons, selects) and defines how their data is packaged and sent to a server. It has three essential attributes: action (where to send), method (how to send), and enctype (encoding for file uploads).
🎬 Live Example
A working form. Press Enter or click Submit — the browser validates before sending.
💡 The required attribute on the inputs triggers native browser validation before the form submits.
Basic Syntax
<form action="/submit" method="POST">
<label for="email">Email</label>
<input type="email" id="email" name="email" required>
<button type="submit">Submit</button>
</form>
The form itself has no visible appearance. It is a container that groups inputs and defines submission behavior.
⚙️ Attributes Reference
| Attribute | Value | Purpose |
|---|---|---|
action | URL | Where to send form data on submit. |
method | GET / POST | How to send the data. Default is GET. |
enctype | application/x-www-form-urlencoded (default), multipart/form-data, text/plain | How to encode data. Required for file uploads. |
autocomplete | on / off | Whether the browser can autofill fields. |
novalidate | boolean | Disable browser validation. |
target | _self, _blank, etc. | Where to display the response. |
accept-charset | charset | Character encoding for the form data. |
name | text | Form name, used in JavaScript. |
GET vs POST — Choosing the Right Method
| Feature | GET | POST |
|---|---|---|
| Data location | URL query string | Request body |
| Visible in URL | Yes | No |
| Bookmarkable | Yes | No |
| Size limit | ~2000 chars | Unlimited |
| Use for | Search, filters | Logins, signups, data changes |
| Secure for passwords | No | Yes |
Rule: Never use GET for anything sensitive (passwords, tokens) or for anything that modifies data on the server. Use POST for both.
File Upload Form
File uploads require method="post" and enctype="multipart/form-data".
<form action="/upload" method="POST" enctype="multipart/form-data">
<label for="avatar">Profile Picture</label>
<input type="file" id="avatar" name="avatar" accept="image/*">
<button type="submit">Upload</button>
</form>
Without enctype="multipart/form-data", the file contents won't be sent — only the filename.
Accessible Form Structure
Group related fields with <fieldset> and <legend>.
<form action="/signup" method="POST">
<fieldset>
<legend>Personal Information</legend>
<label for="name">Full Name</label>
<input type="text" id="name" name="name" required>
<label for="email">Email</label>
<input type="email" id="email" name="email" required>
</fieldset>
<fieldset>
<legend>Account Details</legend>
<label for="username">Username</label>
<input type="text" id="username" name="username" required>
<label for="password">Password</label>
<input type="password" id="password" name="password" required minlength="8">
</fieldset>
<button type="submit">Create Account</button>
</form>
Prevent Submission with JavaScript
Common pattern — validate or submit via AJAX.
<form id="signup-form" action="/signup" method="POST">
<input type="email" name="email" required>
<button type="submit">Sign Up</button>
</form>
<script>
const form = document.getElementById("signup-form");
form.addEventListener("submit", async (e) => {
e.preventDefault(); // Stop the browser's default submit
const data = new FormData(form);
const response = await fetch("/signup", {
method: "POST",
body: data
});
if (response.ok) {
showSuccess();
} else {
showError();
}
});
</script>
Autocomplete Best Practices
Give browsers the right hints so they can autofill correctly.
<form action="/checkout" method="POST">
<input type="text" name="name" autocomplete="name">
<input type="email" name="email" autocomplete="email">
<input type="tel" name="phone" autocomplete="tel">
<input type="text" name="street" autocomplete="street-address">
<input type="text" name="city" autocomplete="address-level2">
<input type="text" name="zip" autocomplete="postal-code">
<input type="text" name="cc-number" autocomplete="cc-number">
<input type="text" name="cc-exp" autocomplete="cc-exp">
<input type="password" name="new-password" autocomplete="new-password">
</form>
Browser autofill reduces typing errors and speeds up checkout by up to 30%. Always use the correct autocomplete values.
🎯 enctype Values
| Value | Use for |
|---|---|
application/x-www-form-urlencoded | Normal text forms (default). |
multipart/form-data | Forms with file uploads. Required. |
text/plain | Debugging only. Rarely used in production. |
⚠️ Common Mistakes
- Using GET for login forms. Passwords appear in the URL, browser history, and server logs. Always use POST for anything sensitive.
- Forgetting enctype for file uploads. Without
multipart/form-data, the file contents aren't sent — only the filename. - Inputs without a name attribute. The input isn't sent to the server. Every input that needs to be submitted must have a
name. - No submit button. Pressing Enter only works if there's a submit button or a single input field. Always include a visible submit button for accessibility.
- Not wrapping inputs in a form. Inputs outside a form still work but can't be submitted together. If the data matters, wrap it in a
<form>. - Using
novalidatewithout replacing validation. If you disable browser validation, you must implement your own. Otherwise users can submit invalid data. - Not testing on mobile. Forms behave differently on mobile — autocomplete, keyboard types, and focus behavior all change.
♿ Accessibility Notes
- Every input needs a label. Placeholders are not labels. Screen readers announce the label when the field is focused.
- Use
<fieldset>and<legend>to group related fields. This helps screen reader users navigate complex forms. - Mark required fields. Use the
requiredattribute (semantic) and a visible asterisk (visual). Screen readers announce the required state. - Announce validation errors. When client-side validation fails, use
aria-live="polite"on the error container so screen readers announce the message. - Test with keyboard only. Tab through the entire form. Focus should be visible and the order should match the visual layout.
- Don't disable the submit button. Disabled buttons aren't focusable. Users don't know why the form won't submit.
❓ Frequently Asked Questions
What is the HTML <form> tag?
The <form> element is a container for interactive controls (inputs, buttons, checkboxes) that collect user data and submit it to a server. It defines how and where the data is sent.
What is the difference between GET and POST?
GET sends form data as URL query parameters — visible in the address bar, limited in size, and not secure for sensitive data. POST sends data in the request body — not visible in the URL, no size limit, and the standard choice for logins, signups, and any data that modifies the server.
What is enctype in a form?
enctype sets the encoding type for form data when using method="post". Use application/x-www-form-urlencoded (default) for normal forms, multipart/form-data for file uploads, and text/plain rarely.
Do I need a form for every input?
If the inputs collect data to be submitted together, yes. Wrap them in a single <form>. Inputs outside a form are only useful for JavaScript-driven interfaces where the data never leaves the page.
How do I prevent a form from submitting?
Use JavaScript: form.addEventListener('submit', e => e.preventDefault()). Use this when you're handling the submission with fetch() and need to keep the page from reloading.