Forms are how websites communicate with users. Login pages, contact forms, checkout flows, survey pages, search bars — they're all HTML forms underneath. If you want to build real, interactive websites, you have to understand forms deeply. This guide covers everything: every input type, validation, accessibility, CSS styling, and complete ready-to-use form templates you can copy right now.
Every form in this guide is copy-paste ready. Paste any example into our free HTML Editor Online Pro and interact with the form live in your browser — test validation, dropdowns, checkboxes, everything. No setup needed.
Every HTML form starts with the <form> element. It's the container that wraps all the input fields, labels, and buttons. The form element has two critical attributes you need to understand before you build anything.
The action attribute tells the browser where to send the form data when the user submits it. This is usually a URL — either a server-side script, an API endpoint, or a third-party service like Formspree. If you leave it empty, the form submits to the same page it's on.
The method attribute tells the browser how to send the data. There are two options — and which one you use matters a lot:
yoursite.com/search?q=html+tutorial. Use GET for search forms or any time the data isn't sensitive and the URL should be bookmarkable.Always use method="POST" for forms that handle passwords, personal information, or any sensitive data. Never use GET for these — GET puts everything in the URL where it can be logged, cached, and seen by anyone looking over the user's shoulder.
Every input field should have a label. Not just for visual design — but for accessibility and usability. When you properly connect a <label> to an <input>, clicking the label text focuses the input. Screen readers announce the label when the input is focused. And on mobile, the tap target becomes much larger and easier to hit.
There are two ways to connect a label to an input — and both are valid:
The name attribute on each input is also critical — it's what the server uses to identify the field data. When the form is submitted, the server receives data like [email protected]. Without a name attribute, the field's data is not sent at all.
Always use labels. An input with no label is inaccessible to screen reader users and is also bad UX for everyone. The only inputs that can sometimes skip a visible label are search boxes — but even those should have an aria-label attribute.
The <input> element is the workhorse of HTML forms. What makes it so powerful is the type attribute — changing this single attribute changes the entire behavior of the field. Here is every input type with real examples.
| Type | What it shows | Key benefit |
|---|---|---|
text | Single-line text box | General purpose text input |
email | Text box with email validation | Browser validates email format. Mobile shows @ keyboard. |
password | Text box with hidden characters | Characters shown as dots. Never stored in browser history. |
tel | Text box for phone numbers | Mobile shows numeric dial pad keyboard |
number | Number input with up/down arrows | Supports min, max, step. Only accepts numbers. |
date | Date picker calendar UI | Browser-native date picker. Returns YYYY-MM-DD. |
checkbox | Tick box — on/off toggle | Multiple checkboxes can all be selected |
radio | Round selection dot | Only one radio button per group can be selected |
range | Draggable slider | Good for ratings, volume, percentage inputs |
color | Color picker swatch | Opens OS color picker. Returns hex value. |
file | File upload button | Use accept to filter file types. multiple for multi-select. |
hidden | Not visible to user | Passes data (user ID, session token, source page) with form |
Beyond <input>, there are three other essential form elements you'll use regularly in real forms.
<fieldset> groups related form fields together, and <legend> provides a title for that group. This is especially useful for forms with multiple sections — like a shipping address and billing address — and it's a significant accessibility improvement for screen readers.
One of the best things about HTML5 is built-in form validation. You don't need to write a single line of JavaScript for basic validation — the browser handles it automatically. These validation attributes work in all modern browsers.
Pattern examples you'll use in real projects:
pattern="[0-9]{6}" — Exactly 6 digits (Indian PIN code)pattern="[A-Za-z]{3,}" — At least 3 letters onlypattern="\d{10}" — Exactly 10 digits (phone number)pattern="[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}" — Email regexpattern="https?://.+" — URL starting with http:// or https://Always add a title attribute alongside pattern. When validation fails, the browser shows the title text as the error message. Without it, users get a generic "Please match the requested format" message that tells them nothing useful.
Unstyled HTML forms are ugly. Browser defaults look different across Chrome, Firefox, and Safari. CSS gives you complete control over how forms look — and a well-designed form dramatically improves conversion rates and user experience.
This is a complete, professional contact form with full validation, accessible labels, and clean CSS styling. Copy it, customize the colors and text, connect it to Formspree, and it's ready to use on a real website.
Login and registration forms are the most common forms on the internet. Here's a clean, professional login form with all the right attributes — password autocomplete, proper input types, and clean validation.
Always use autocomplete on login forms. autocomplete="email" and autocomplete="current-password" tell the browser and password managers (LastPass, 1Password, browser built-in) that these are the login fields. This enables autofill, which users love. Never disable autocomplete on login forms — it's a UX mistake.
Copy any form from this guide, paste it into HTML Editor Online Pro, and interact with it immediately. Test the validation, try the inputs on mobile view, see how it looks on iPhone. No download, no login needed.
📬 Open HTML Editor Free →These are the mistakes almost every beginner makes with HTML forms. Knowing them upfront saves you a lot of debugging time.
Never use method="GET" for passwords, personal data, or payment info. GET puts everything in the URL. Use method="POST" for anything sensitive — always.
An input without a name attribute won't have its data submitted with the form. The server never receives it. Every input that should send data needs a name. This is the number one reason "my form isn't sending data" issues happen.
Using placeholder text as the only label looks clean but is terrible for usability. When a user starts typing, the placeholder disappears — they can no longer see what the field is for. Always have a real <label> element. Placeholder should be an example, not the label.
Many developers remove the browser's default outline with outline: none because they think it looks ugly. But the focus outline is a critical accessibility feature — keyboard users rely on it to know where they are in the form. If you remove it, always replace it with a custom focus style using :focus { box-shadow: 0 0 0 3px rgba(106,110,219,.3); }.
Forms behave very differently on mobile. The keyboard pops up and changes the viewport height. Input types like tel, email, and number trigger different keyboards. Checkboxes can be too small to tap. Always test every form on a real mobile device or simulator before publishing.
When a user submits a form, they need immediate feedback. "Was my message sent? Did it work? Did it fail?" Without feedback, users submit the form multiple times or leave thinking it didn't work. Always redirect to a thank-you page or show a success message after submission.
Q: How do I make an HTML form actually send emails?
HTML alone can't send emails — you need a backend service. The easiest free option is Formspree (formspree.io). Sign up, create a form, get your form endpoint URL, and use it as the form's action attribute. Form submissions go straight to your email. The free plan handles 50 submissions per month.
Q: What is the difference between GET and POST in forms?
GET sends form data in the URL (site.com/search?q=html) — visible, bookmarkable, but not secure. POST sends data in the request body — not visible in the URL, not saved in browser history, and appropriate for sensitive data. Use GET for search forms. Use POST for everything else.
Q: How do I prevent form resubmission on page refresh?
This is the "confirm form resubmission" dialog users see when refreshing after a form POST. The solution is the Post/Redirect/Get (PRG) pattern: after the form is successfully processed on the server, redirect the user to a new URL (like a thank-you page). Now refreshing just reloads the thank-you page, not resubmitting the form.
Q: Can I style file input buttons?
File inputs are notoriously difficult to style with CSS because of browser security restrictions. The most reliable approach: hide the real file input with opacity: 0; position: absolute and place a styled button on top of it. Clicking the styled button triggers the hidden input. Alternatively, use JavaScript's FileReader API for a completely custom file upload UI.
Q: How do I disable the browser's autocomplete?
Add autocomplete="off" to the form element or individual inputs. But think twice before doing this — autocomplete is a convenience that users love. The only cases where disabling it makes sense are one-time-use fields like OTPs or security questions where autofill could be a security risk.
Q: How do I make radio buttons work together as a group?
All radio buttons that belong to the same group must have the exact same name attribute value. The browser uses the name to understand which buttons are alternatives to each other — selecting one deselects the others in the same name group. The value attribute determines what data is sent when that specific button is selected.