In this lesson you will
- Connect every field to a visible label
- Choose input types that help on phones
- Use built-in validation and know its limits
form, label and name
<form> groups fields and sends them when submitted. action is where the data goes and method is how: get puts it in the URL (good for searches), post sends it in the request body (use it for anything that changes data or is private). Without action, the form submits to the current page.
Every field needs a label. <label for="email">Email</label> connects to <input id="email">. Clicking the label then focuses the field (a bigger tap target on phones), and screen readers read the label when the field is focused. Placeholder text is not a label: it disappears when you type and is often too pale to read.
name is the key the browser sends with the value, like email=ali@example.com. A field without a name is not submitted at all, which is a common reason why "the form sends nothing". In the editor below, submitting shows the data in the console.
Console
- Console messages, errors, form data and clicked links appear here.
Press Send with the fields empty: the browser stops you. Fill them in and press Send again: the console shows exactly what would be sent.
Input types and choices
The type attribute changes the keyboard and the checks. email shows the @ key and checks the format, tel shows a number pad, number allows only numbers (with min, max and step), url checks for a web address, date opens a date picker and password hides the characters. search, color, range, time and file exist too.
For one choice from a short list, use radio buttons that share the same name; for several choices, checkboxes. Group them in <fieldset> with a <legend> that asks the question, so screen readers read "Delivery: Standard, radio button". For a long list, such as countries, use <select> with <option> elements.
The autocomplete attribute, such as autocomplete="email" or "tel", lets browsers fill saved details. It makes forms much faster on phones and is part of WCAG accessibility guidance.
Console
- Console messages, errors, form data and clicked links appear here.
Built-in validation, and why the server must check too
required stops an empty submit, minlength/maxlength limit text length, min/max limit numbers and dates, and pattern takes a regular expression, such as pattern="[0-9]{6}" for a six-digit code. The browser shows its own message in the visitor’s language and focuses the first wrong field.
Browser checks are for convenience only. Anyone can turn them off or send data straight to your server without the form. Every rule must be checked again on the server before you save or act on the data; the Node.js and security courses show how.
Use <button type="submit"> for the main action. A <button> inside a form submits by default, so a button that does something else, such as "Show password", needs type="button".
Common mistakes
Placeholder instead of label
A field with only a placeholder has no lasting label. People forget what the box was for after typing, and screen readers may not announce it. Always add
<label>.Forgetting name
Fields without
nameare silently left out of the submitted data. Check the console in the editor above to see it happen.Trusting browser validation
requiredandpatterncan be bypassed in seconds. Validate again on the server, every time.
Exercise
Make a booking form: a required name field and an email field (type="email"), each with a matching label; a fieldset with a legend and two radio buttons that share one name; and a submit button. Every input needs a name.
Console
- Console messages, errors, form data and clicked links appear here.
- At least two labels connected with
for - A field with
required - An email field with
type="email" - A
fieldsetwith alegend - Two radio buttons with a
name - Every input has a
name - A submit button
Show one possible solution
<form method="post">
<p><label for="n">Name</label><br>
<input id="n" name="name" required></p>
<p><label for="e">Email</label><br>
<input id="e" name="email" type="email" required></p>
<fieldset>
<legend>Session</legend>
<label><input type="radio" name="session" value="morning" required> Morning</label>
<label><input type="radio" name="session" value="evening"> Evening</label>
</fieldset>
<button type="submit">Book</button>
</form>Quick quiz
Finished the lesson?
Questions people ask
Can HTML send form data to my email without a server?
Not reliably. action="mailto:..." only opens the visitor’s email app and fails for many people. You need something on a server, your own or a form service, to receive the data and send the email.
How do I change the browser’s validation message?
With JavaScript: setCustomValidity() sets your own message, and the title attribute adds a hint shown with pattern errors in some browsers. Many sites show their own message next to the field instead.
Should I use GET or POST?
GET for searches and filters, because the result can be bookmarked and shared. POST for logins, payments, messages and anything that creates or changes data, so it is not stored in the URL and browser history.
How do I accept Arabic and English names in one field?
Use a plain text input with no pattern that limits letters, and add dir="auto" so the text direction follows what the person types. Avoid rules like "letters A to Z only", which reject real names.
Is a date input reliable on all browsers?
type="date" is supported in all current major browsers. The picker looks different on each one, and the value is always sent as YYYY-MM-DD whatever format the visitor sees.
Sources
Facts in this lesson were checked against these official pages on 20 October 2026.
Code examples stay in English and run in a sandbox on your device. Arabic text is pending native review. If you spot a mistake, tell us through the contact page.