<form>
| Since: | HTML 4(1997) |
|---|
The <form> element is a container for user input that submits data to a server. You specify the destination URL and submission method using attributes.
Syntax
<form action="destination-url" method="post"> <!-- Place form controls here --> <input type="text" name="username"> <button type="submit">Submit</button> </form>
Attributes
| Attribute | Description |
|---|---|
| action | Specifies the URL to which the form data is submitted. If omitted, the data is sent to the current page's URL. |
| method | Specifies the submission method. Use get (appends data to the URL) or post (includes data in the request body). |
| enctype | Specifies the encoding type for the submitted data. Use multipart/form-data when the form includes file uploads. |
| novalidate | When present, disables the browser's built-in form validation. |
| autocomplete | Enables (on) or disables (off) autocomplete for the entire form. |
| target | Specifies the browsing context in which to display the response. Use _blank to open it in a new tab. |
Sample Code
sample_form.html
<!-- Basic contact form (POST submission) -->
<form action="/contact.php" method="post" autocomplete="on">
<div>
<label for="name">Name (required)</label>
<input type="text" id="name" name="name" required>
</div>
<div>
<label for="email">Email address (required)</label>
<input type="email" id="email" name="email" required>
</div>
<div>
<label for="message">Message</label>
<textarea id="message" name="message" rows="5"></textarea>
</div>
<button type="submit">Send</button>
</form>
<!-- Search form (GET submission): data is appended to the URL -->
<form action="/search" method="get">
<input type="search" name="q" placeholder="Enter keyword">
<button type="submit">Search</button>
</form>
<!-- Resulting URL example: /search?q=HTML -->
<!-- File upload form (enctype is required) -->
<form action="/upload.php" method="post" enctype="multipart/form-data">
<label for="file">Choose a file:</label>
<input type="file" id="file" name="file" accept="image/*">
<button type="submit">Upload</button>
</form>
Output
A text field for name, an email field, a textarea, and a submit button are displayed. Clicking "Send" validates the input, and if there are no errors, the data is submitted via POST to /contact.php. The search form appends the input as a URL parameter after submission (e.g., /search?q=HTML). The file upload form restricts selection to image files via the accept attribute.
Collecting Form Data with the FormData API
The JavaScript FormData object makes it easy to collect form values and send them via AJAX without reloading the page.
<form id="contactForm">
<input type="text" name="name" placeholder="Name" required>
<input type="email" name="email" placeholder="Email" required>
<textarea name="message" rows="4"></textarea>
<button type="submit">Send</button>
</form>
<script>
document.getElementById('contactForm').addEventListener('submit', function(e) {
e.preventDefault(); // Prevent default form submission
var formData = new FormData(this); // Collect all field values automatically
// Access individual values
console.log(formData.get('name'));
console.log(formData.get('email'));
// Send via fetch (Content-Type is automatically set to multipart/form-data)
fetch('/api/contact', {
method: 'POST',
body: formData
})
.then(function(res) { return res.json(); })
.then(function(data) {
alert('Sent successfully');
});
});
</script>
Styling Forms with CSS
Form elements look different across browsers by default. Override the default styles with CSS to create a consistent design.
<style>
form { max-width: 480px; }
/* Stack label and input vertically */
.form-group {
display: flex;
flex-direction: column;
gap: 4px;
margin-bottom: 16px;
}
/* Shared styles for text inputs and textarea */
input[type="text"],
input[type="email"],
textarea {
width: 100%;
padding: 8px 12px;
border: 1px solid #ccc;
border-radius: 4px;
font-size: 1rem;
box-sizing: border-box;
transition: border-color 0.2s;
}
/* Highlight border on focus */
input:focus, textarea:focus {
outline: none;
border-color: #4a90e2;
box-shadow: 0 0 0 3px rgba(74, 144, 226, 0.2);
}
/* Error state */
input:invalid:not(:placeholder-shown) {
border-color: #e74c3c;
}
/* Submit button */
button[type="submit"] {
padding: 10px 24px;
background: #4a90e2;
color: #fff;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 1rem;
}
button[type="submit"]:hover { background: #2c6fbc; }
</style>
Notes
Use method="get" when you want the data to appear in the URL, such as for search forms. Use method="post" when submitting sensitive data such as passwords or personal information that should not be visible in the URL. Always use method="post" for forms that handle passwords or personal information, and make sure the page is served over HTTPS.
The default value of the enctype attribute is application/x-www-form-urlencoded, which works fine for ordinary text data. If the form includes a file upload, you must specify multipart/form-data. Without it, the file will not be submitted correctly.
For input controls you can place inside a form (such as text fields), see input (text-based).
Browser Compatibility
1 and later ○
1 and later ○
3 and later ○
2 and earlier ×
8 ○
7 ○
6 ○
14 and earlier ×
2 and later ○
Android Browser
4.4 and later ○
4 and earlier ×* Version data based on MDN.
Integration with JavaScript (FormData)
The FormData API makes it easy to retrieve and submit form data from JavaScript. It is the standard approach for submitting forms asynchronously via Ajax.
<form id="contact-form">
<label for="name">Name</label>
<input type="text" id="name" name="name" required>
<label for="message">Message</label>
<textarea id="message" name="message" required></textarea>
<button type="submit">Send</button>
<p id="result"></p>
</form>
<script>
document.getElementById('contact-form').addEventListener('submit', function(e) {
e.preventDefault(); // Prevent the default form submission
// Use FormData to retrieve all form values at once
var formData = new FormData(this);
// Submit asynchronously with the fetch API
fetch('/api/contact', {
method: 'POST',
body: formData // Content-Type is automatically set to multipart/form-data
})
.then(function(response) {
return response.json();
})
.then(function(data) {
document.getElementById('result').textContent = 'Your message has been sent.';
})
.catch(function(error) {
document.getElementById('result').textContent = 'Sending failed. Please try again.';
});
});
</script>
Accessibility Best Practices
Key points for making forms accessible.
| Item | How to Implement |
|---|---|
| Provide a label for every input | Match the for attribute of label with the id of the input (placeholder alone is not sufficient) |
| Visually indicate required fields | Display a "* (required)" marker with CSS, and also set aria-required="true" |
| Associate errors with their input | Use aria-describedby to link the error message element to the input |
| Group related inputs | Wrap related inputs in a fieldset/legend to give the group a name |
| Communicate submission results | Display success/failure messages in an aria-live="polite" region |
If you find any errors or copyright issues, please contact us.