An HTML form collects structured input from visitors—such as login credentials, search queries, contact messages, or checkout details—and sends it to a server or JavaScript handler. Every form starts with the form container wrapping labeled controls and a submit button.
flowchart LR
A["User fills inputs"] --> B["Browser checks HTML validation"]
B --> C["Submit event fires"]
C --> D["GET query string or POST request body"]
D --> E["Backend endpoint processes data"]
Every input inside a form needs two things to work smoothly:
name attribute: When the form submits, the browser pairs each input's name with the user's typed value. Inputs without a name are left out of the submission.label: Connect label for="field-id" to the input's id="field-id". Clicking the label focuses the input, and screen readers announce the label automatically.<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>HTML Forms Demo</title>
<style>
form { max-width: 420px; font-family: system-ui, sans-serif; display: grid; gap: 12px; }
label { font-weight: 600; display: block; margin-bottom: 4px; }
input, button { padding: 10px; font-size: 1rem; border-radius: 6px; border: 1px solid #cbd5e1; width: 100%; box-sizing: border-box; }
button { background: #2563eb; color: #ffffff; border: none; cursor: pointer; }
</style>
</head>
<body>
<form action="/api/contact" method="post">
<div>
<label for="full-name">Full Name</label>
<input id="full-name" name="full_name" type="text" required autocomplete="name">
</div>
<div>
<label for="contact-email">Email Address</label>
<input id="contact-email" name="email" type="email" required autocomplete="email">
</div>
<button type="submit">Send Message</button>
</form>
</body>
</html>
Use method="get" for search boxes and filters where bookmarking the URL query string (?q=html) helps users. Always use method="post" for forms that create data, update records, or send passwords and private fields.
placeholder instead of label: Placeholders vanish as soon as the user starts typing and fail accessibility audits. Always keep a visible label.name on inputs: Forgotten name attributes result in empty payloads reaching your backend controller.required and type="email" improve UX, but users can bypass them in DevTools—always re-validate on the backend.The browser defaults to method="get", appending every named input value onto the page URL as query parameters.
A button with type="submit" is preferred because it can hold icons or rich text and is easier to style consistently.
Sign in to track your learning journey, earn industry-recognized certificates, and join our elite developer community.
Quick Access With
Experiment with the code from this lesson in our interactive playground.
You've completed this section! Take a quick 5-question quiz to check your understanding.