Syntax
<form action="/submit" method="POST">
<label for="field">Label:</label>
<input type="text" id="field" name="field">
<button type="submit">Submit</button>
</form>Breaking down the syntax
action- The URL that receives a submission.
method- GET puts values in the URL; POST sends them in the request body.
name- Identifies a successful control in submitted form data.
for / id- Connect a visible label to its control.
How it works
A form groups controls into named values that can be sent together. Labels tell people what to enter; name attributes tell the receiving application what each value means.
Label
The user understands the requested value.
Input
The browser collects values and can check constraints.
Submit
The receiving server must validate the submitted data again.
Examples
A labelled input
Try submitting an empty or malformed address. The documentation preview blocks navigation and submission.
<form>
<label for="email">Email address</label>
<input id="email" name="email" type="email" required>
<button type="submit">Check email</button>
</form>- for matches id, giving the input an accessible name.
- name supplies the field key when a real form is submitted.
- required and type provide browser validation.
Basic Contact Form
A simple contact form with name, email, and message fields.
<form action="/contact" method="POST">
<div>
<label for="name">Full Name:</label>
<input type="text" id="name" name="name" placeholder="John Doe" required>
</div>
<div>
<label for="email">Email:</label>
<input type="email" id="email" name="email" placeholder="john@example.com" required>
</div>
<div>
<label for="message">Message:</label>
<textarea id="message" name="message" rows="5" placeholder="Your message..."></textarea>
</div>
<button type="submit">Send Message</button>
</form>Login Form
A login form with username, password, and remember me checkbox.
<form action="/login" method="POST">
<div>
<label for="username">Username:</label>
<input type="text" id="username" name="username" autocomplete="username" required>
</div>
<div>
<label for="password">Password:</label>
<input type="password" id="password" name="password" autocomplete="current-password" required>
</div>
<div>
<input type="checkbox" id="remember" name="remember">
<label for="remember">Remember me</label>
</div>
<button type="submit">Log In</button>
<a href="/forgot-password">Forgot password?</a>
</form>Multi-Step Registration Form
A comprehensive registration form with fieldsets grouping related inputs.
<form action="/register" method="POST">
<fieldset>
<legend>Personal Info</legend>
<label for="fname">First Name:</label>
<input type="text" id="fname" name="fname" required>
<label for="lname">Last Name:</label>
<input type="text" id="lname" name="lname" required>
<label for="dob">Date of Birth:</label>
<input type="date" id="dob" name="dob" required>
</fieldset>
<fieldset>
<legend>Account Details</legend>
<label for="reg-email">Email:</label>
<input type="email" id="reg-email" name="email" required>
<label for="reg-pass">Password:</label>
<input type="password" id="reg-pass" name="password" minlength="8" required>
<label for="confirm-pass">Confirm Password:</label>
<input type="password" id="confirm-pass" name="confirm_password" required>
</fieldset>
<button type="submit">Create Account</button>
</form>Best practices
- Always associate labels with inputs using matching for and id attributes
- Use the appropriate input type (email, tel, date) to trigger correct mobile keyboards
- Include the required attribute on mandatory fields and validate both client and server side
- Group related form controls with fieldset and legend elements
- Use autocomplete attributes to help browsers autofill common fields
- Provide clear error messages and visual feedback when validation fails
Browser compatibility
Support applies to the named feature, not every attribute or behaviour in this article. Versions refer to browsers, not operating systems.
<form>
Desktop
- Chrome
- Supported
From 1 - Firefox
- Supported
From 1 - Safari
- Supported
From 3 - Edge
- Supported
From 12 - Opera
- Supported
From 15
Mobile
- Safari on iOS
- Supported
From 2 - Chrome for Android
- Supported
From 18 - Firefox for Android
- Supported
From 4 - Samsung Internet
- Supported
From 1.0
MDN BCD record for this feature · MDN reference
Support history and limitations
Chrome
- From 1
Firefox
- From 1
Safari
- From 3
Edge
- From 12
Opera
- From 15
Safari on iOS
- From 2
Chrome for Android
- From 18
Firefox for Android
- From 4
Samsung Internet
- From 1.0
<form> action
Desktop
- Chrome
- Supported
From 1 - Firefox
- Supported
From 1 - Safari
- Supported
From 3 - Edge
- Supported
From 12 - Opera
- Supported
From 15
Mobile
- Safari on iOS
- Supported
From 2 - Chrome for Android
- Supported
From 18 - Firefox for Android
- Supported
From 4 - Samsung Internet
- Supported
From 1.0
MDN BCD record for this feature
Support history and limitations
Chrome
- From 1
Firefox
- From 1
Safari
- From 3
Edge
- From 12
Opera
- From 15
Safari on iOS
- From 2
Chrome for Android
- From 18
Firefox for Android
- From 4
Samsung Internet
- From 1.0
<form> method
Desktop
- Chrome
- Supported
From 1 - Firefox
- Supported
From 1 - Safari
- Supported
From 3 - Edge
- Supported
From 12 - Opera
- Supported
From 15
Mobile
- Safari on iOS
- Supported
From 2 - Chrome for Android
- Supported
From 18 - Firefox for Android
- Supported
From 4 - Samsung Internet
- Supported
From 1.0
MDN BCD record for this feature
Support history and limitations
Chrome
- From 1
Firefox
- From 1
Safari
- From 3
Edge
- From 12
Opera
- From 15
Safari on iOS
- From 2
Chrome for Android
- From 18
Firefox for Android
- From 4
Samsung Internet
- From 1.0
<form> enctype
Desktop
- Chrome
- Supported
From 1 - Firefox
- Supported
From 1 - Safari
- Supported
From 3 - Edge
- Supported
From 12 - Opera
- Supported
From 15
Mobile
- Safari on iOS
- Supported
From 2 - Chrome for Android
- Supported
From 18 - Firefox for Android
- Supported
From 4 - Samsung Internet
- Supported
From 1.0
MDN BCD record for this feature
Support history and limitations
Chrome
- From 1
Firefox
- From 1
Safari
- From 3
Edge
- From 12
Opera
- From 15
Safari on iOS
- From 2
Chrome for Android
- From 18
Firefox for Android
- From 4
Samsung Internet
- From 1.0
<form> novalidate
Desktop
- Chrome
- Supported
From 10 - Firefox
- Supported
From 4 - Safari
- Supported
From 10.1 - Edge
- Supported
From 12 - Opera
- Supported
From 15
Mobile
- Safari on iOS
- Supported
From 10.3 - Chrome for Android
- Supported
From 18 - Firefox for Android
- Supported
From 4 - Samsung Internet
- Supported
From 1.0
MDN BCD record for this feature
Support history and limitations
Chrome
- From 10
Firefox
- From 4
Safari
- From 10.1
Edge
- From 12
Opera
- From 15
Safari on iOS
- From 10.3
Chrome for Android
- From 18
Firefox for Android
- From 4
Samsung Internet
- From 1.0
<input>
Desktop
- Chrome
- Supported
From 1 - Firefox
- Supported
From 1 - Safari
- Supported
From 1 - Edge
- Supported
From 12 - Opera
- Supported
By 12.1 (possibly earlier)
Mobile
- Safari on iOS
- Supported
From 1 - Chrome for Android
- Supported
From 18 - Firefox for Android
- Supported
From 4 - Samsung Internet
- Supported
From 1.0
MDN BCD record for this feature · MDN reference
Support history and limitations
Chrome
- From 1
Firefox
- From 1 · Before Firefox 89, manipulating the content of <input> elements using Document.execCommand() commands requires workarounds (see bug 1220696).
Safari
- From 1
Edge
- From 12
Opera
- By 12.1 (possibly earlier)
Safari on iOS
- From 1
Chrome for Android
- From 18
Firefox for Android
- From 4 · Before Firefox for Android 89, manipulating the content of <input> elements using Document.execCommand() commands requires workarounds (see bug 1220696).
Samsung Internet
- From 1.0
<button>
Desktop
- Chrome
- Supported
From 1 - Firefox
- Supported
From 1 - Safari
- Supported
From 1 - Edge
- Supported
From 12 - Opera
- Supported
By 15 (possibly earlier)
Mobile
- Safari on iOS
- Supported
From 1 - Chrome for Android
- Supported
From 18 - Firefox for Android
- Supported
From 4 - Samsung Internet
- Supported
From 1.0
MDN BCD record for this feature · MDN reference
Support history and limitations
Chrome
- From 1
Firefox
- From 1
Safari
- From 1
Edge
- From 12
Opera
- By 15 (possibly earlier)
Safari on iOS
- From 1
Chrome for Android
- From 18
Firefox for Android
- From 4
Samsung Internet
- From 1.0
<label>
Desktop
- Chrome
- Supported
From 1 - Firefox
- Supported
From 1 - Safari
- Supported
By 4 (possibly earlier) - Edge
- Supported
From 12 - Opera
- Supported
From 15
Mobile
- Safari on iOS
- Supported
By 3.2 (possibly earlier) - Chrome for Android
- Supported
From 18 - Firefox for Android
- Supported
From 4 - Samsung Internet
- Supported
From 1.0
MDN BCD record for this feature · MDN reference
Support history and limitations
Chrome
- From 1
Firefox
- From 1
Safari
- By 4 (possibly earlier)
Edge
- From 12
Opera
- From 15
Safari on iOS
- By 3.2 (possibly earlier)
Chrome for Android
- From 18
Firefox for Android
- From 4
Samsung Internet
- From 1.0
<textarea>
Desktop
- Chrome
- Supported
From 1 - Firefox
- Supported
From 1 - Safari
- Supported
By 4 (possibly earlier) - Edge
- Supported
From 12 - Opera
- Supported
By 12.1 (possibly earlier)
Mobile
- Safari on iOS
- Supported
By 3 (possibly earlier) - Chrome for Android
- Supported
From 18 - Firefox for Android
- Supported
From 4 - Samsung Internet
- Supported
From 1.0
MDN BCD record for this feature · MDN reference
Support history and limitations
Chrome
- From 1
Firefox
- From 1 · Before Firefox 6, when a <textarea> was focused, the insertion point was placed at the end of the text by default. Other major browsers place the insertion point at the beginning of the text. · A default background-image gradient is applied to all <textarea> elements, which can be disabled using background-image: none. · Before Firefox 89, manipulating the content of <textarea> elements using Document.execCommand() commands requires workarounds (see bug 1220696).
Safari
- By 4 (possibly earlier)
Edge
- From 12
Opera
- By 12.1 (possibly earlier)
Safari on iOS
- By 3 (possibly earlier) · Unlike other major browsers, a default style of opacity: 0.4 is applied to disabled <textarea> elements.
Chrome for Android
- From 18
Firefox for Android
- From 4 · Before Firefox for Android 6, when a <textarea> was focused, the insertion point was placed at the end of the text by default. Other major browsers place the insertion point at the beginning of the text. · A default background-image gradient is applied to all <textarea> elements, which can be disabled using background-image: none. · Before Firefox for Android 89, manipulating the content of <textarea> elements using Document.execCommand() commands requires workarounds (see bug 1220696).
Samsung Internet
- From 1.0
<select>
Desktop
- Chrome
- Supported
From 1 - Firefox
- Supported
From 1 - Safari
- Supported
From 1 - Edge
- Supported
From 12 - Opera
- Supported
From 2
Mobile
- Safari on iOS
- Supported
From 1 - Chrome for Android
- Supported
From 18 - Firefox for Android
- Supported
From 4 - Samsung Internet
- Supported
From 1.0
MDN BCD record for this feature · MDN reference
Support history and limitations
Chrome
- From 1 · border-radius on <select> elements is ignored unless -webkit-appearance is overridden to an appropriate value.
Firefox
- From 1 · Historically, Firefox has allowed keyboard and mouse events to bubble up from the <option> element to the parent <select> element, although this behavior is inconsistent across many browsers. For better Web compatibility (and for technical reasons), when Firefox is in multi-process mode the <select> element is displayed as a drop-down list. The behavior is unchanged if the <select> is presented inline and it has either the multiple attribute defined or a size attribute set to more than 1. Rather than watching <option> elements for events, you should watch for change events on <select>. See bug 1090602 for details.
Safari
- From 1 · border-radius on <select> elements is ignored unless -webkit-appearance is overridden to an appropriate value.
Edge
- From 12
Opera
- From 2
Safari on iOS
- From 1 · border-radius on <select> elements is ignored unless -webkit-appearance is overridden to an appropriate value.
Chrome for Android
- From 18 · border-radius on <select> elements is ignored unless -webkit-appearance is overridden to an appropriate value.
Firefox for Android
- From 4 · Firefox for Android, by default, sets a background-image gradient on all <select multiple> elements. This can be disabled using background-image: none.
Samsung Internet
- From 1.0 · border-radius on <select> elements is ignored unless -webkit-appearance is overridden to an appropriate value.
<fieldset>
Desktop
- Chrome
- Supported
From 1 - Firefox
- Supported
From 1 - Safari
- Supported
By 4 (possibly earlier) - Edge
- Supported
From 12 - Opera
- Supported
By 15 (possibly earlier)
Mobile
- Safari on iOS
- Supported
By 3.2 (possibly earlier) - Chrome for Android
- Supported
From 18 - Firefox for Android
- Supported
From 4 - Samsung Internet
- Supported
From 1.0
MDN BCD record for this feature · MDN reference
Support history and limitations
Chrome
- From 1 · Before version 86, this element did not support flexbox and grid layouts within this element. See bug 41027853.
Firefox
- From 1
Safari
- By 4 (possibly earlier)
Edge
- From 12 · Before version 86, this element did not support flexbox and grid layouts within this element. See bug 4511145.
Opera
- By 15 (possibly earlier)
Safari on iOS
- By 3.2 (possibly earlier)
Chrome for Android
- From 18 · Before version 86, this element did not support flexbox and grid layouts within this element. See bug 41027853.
Firefox for Android
- From 4
Samsung Internet
- From 1.0 · Before version 14.0, this element did not support flexbox and grid layouts within this element. See bug 41027853.
<legend>
Desktop
- Chrome
- Supported
From 1 - Firefox
- Supported
From 1 - Safari
- Supported
From 3 - Edge
- Supported
From 12 - Opera
- Supported
By 12.1 (possibly earlier)
Mobile
- Safari on iOS
- Supported
From 1 - Chrome for Android
- Supported
From 18 - Firefox for Android
- Supported
From 4 - Samsung Internet
- Supported
From 1.0
MDN BCD record for this feature · MDN reference
Support history and limitations
Chrome
- From 1
Firefox
- From 1
Safari
- From 3
Edge
- From 12
Opera
- By 12.1 (possibly earlier)
Safari on iOS
- From 1
Chrome for Android
- From 18
Firefox for Android
- From 4
Samsung Internet
- From 1.0
<input> type="text"
Desktop
- Chrome
- Supported
From 1 - Firefox
- Supported
From 1 - Safari
- Supported
From 1 - Edge
- Supported
From 12 - Opera
- Supported
From 15
Mobile
- Safari on iOS
- Supported
From 1 - Chrome for Android
- Supported
From 18 - Firefox for Android
- Supported
From 4 - Samsung Internet
- Supported
From 1.0
MDN BCD record for this feature · MDN reference
Support history and limitations
Chrome
- From 1
Firefox
- From 1
Safari
- From 1
Edge
- From 12
Opera
- From 15
Safari on iOS
- From 1
Chrome for Android
- From 18
Firefox for Android
- From 4
Samsung Internet
- From 1.0
<input> type="email"
Desktop
- Chrome
- Supported
From 5 - Firefox
- Supported
From 1 - Safari
- Supported
From 5 - Edge
- Supported
From 12 - Opera
- Supported
From 11
Mobile
- Safari on iOS
- Supported
From 3 - Chrome for Android
- Supported
From 18 - Firefox for Android
- Supported
From 4 - Samsung Internet
- Supported
From 1.0
MDN BCD record for this feature · MDN reference
Support history and limitations
Chrome
- From 5
Firefox
- From 1
Safari
- From 5
Edge
- From 12
Opera
- From 11
Safari on iOS
- From 3 · Doesn't do validation, but instead offers a custom 'email' keyboard, which is designed to make entering email addresses easier. · The custom 'email' keyboard does not provide a comma key, so users cannot enter multiple email addresses. · Automatically applies a default style of opacity: 0.4 to disable textual <input> elements, including those of type 'email'. Other major browsers don't currently share this particular default style.
Chrome for Android
- From 18
Firefox for Android
- From 4
Samsung Internet
- From 1.0
<input> type="password"
Desktop
- Chrome
- Supported
From 1 - Firefox
- Supported
From 1 - Safari
- Supported
From 1 - Edge
- Supported
From 12 - Opera
- Supported
From 2
Mobile
- Safari on iOS
- Supported
From 1 - Chrome for Android
- Supported
From 18 - Firefox for Android
- Supported
From 4 - Samsung Internet
- Supported
From 1.0
MDN BCD record for this feature · MDN reference
Support history and limitations
Chrome
- From 1
Firefox
- From 1
Safari
- From 1
Edge
- From 12
Opera
- From 2
Safari on iOS
- From 1
Chrome for Android
- From 18
Firefox for Android
- From 4
Samsung Internet
- From 1.0
<input> required
Desktop
- Chrome
- Supported
From 4 - Firefox
- Supported
From 4 - Safari
- Supported
From 5 - Edge
- Supported
From 12 - Opera
- Supported
By 12.1 (possibly earlier)
Mobile
- Safari on iOS
- Supported
From 4 - Chrome for Android
- Supported
From 18 - Firefox for Android
- Supported
From 4 - Samsung Internet
- Supported
From 1.0
MDN BCD record for this feature · MDN reference
Support history and limitations
Chrome
- From 4
Firefox
- From 4
Safari
- From 5
Edge
- From 12
Opera
- By 12.1 (possibly earlier)
Safari on iOS
- From 4
Chrome for Android
- From 18
Firefox for Android
- From 4
Samsung Internet
- From 1.0
<input> minlength
Desktop
- Chrome
- Supported
From 40 - Firefox
- Supported
From 51 - Safari
- Supported
From 10.1 - Edge
- Supported
From 17 - Opera
- Supported
From 27
Mobile
- Safari on iOS
- Supported
From 10.3 - Chrome for Android
- Supported
From 40 - Firefox for Android
- Supported
From 51 - Samsung Internet
- Supported
From 4.0
MDN BCD record for this feature · MDN reference
Support history and limitations
Chrome
- From 40
Firefox
- From 51
Safari
- From 10.1
Edge
- From 17
Opera
- From 27
Safari on iOS
- From 10.3
Chrome for Android
- From 40
Firefox for Android
- From 51
Samsung Internet
- From 4.0
HTMLFormElement.checkValidity
Desktop
- Chrome
- Supported
From 4 - Firefox
- Supported
From 4 - Safari
- Supported
From 5 - Edge
- Supported
From 12 - Opera
- Supported
By 12.1 (possibly earlier)
Mobile
- Safari on iOS
- Supported
From 4 - Chrome for Android
- Supported
From 18 - Firefox for Android
- Supported
From 4 - Samsung Internet
- Supported
From 1.0
MDN BCD record for this feature · MDN reference
Support history and limitations
Chrome
- From 4
Firefox
- From 4
Safari
- From 5
Edge
- From 12
Opera
- By 12.1 (possibly earlier)
Safari on iOS
- From 4
Chrome for Android
- From 18
Firefox for Android
- From 4
Samsung Internet
- From 1.0
MDN BCD 8.1.5 · Dataset built 2026-10-08 · Mapping reviewed 2026-10-21. These dates are not individual browser-test or claim-verification dates. Unknown means the data does not establish support.
When should I use this?
Use a form to collect and submit input, including searches, preferences and sign-in details.
Common mistakes
An input without a name
An id helps connect the label, but does not name the submitted value.
Incorrect
<input id="email" type="email">Corrected
<label for="email">Email</label>
<input id="email" name="email" type="email">Compare approaches
- GET: Read-only searches and URLs users can bookmark.
- POST: Submitting changes or data that should not be placed in a URL. HTTPS is still needed.
Accessibility
- Keep visible labels; placeholders are hints, not replacements.
- Explain errors in text and connect them to the relevant controls.
- Group related choices with fieldset and legend.
Explore deeper
Browser checks are a convenience
required and type="email" help users catch mistakes but can be bypassed. Validate input and permissions on the server. Never put passwords in a GET query.