—HTML Series · Post 11: HTML Forms
HTML Forms:
The Most Critical Skill
Contact forms, login screens, sign-up flows, search bars, checkout pages — forms are everywhere. If you can't build forms, you can't build the web.
Every meaningful interaction on the web starts with a form. Logging into your email? Form. Searching Google? Form. Buying something online? Form. Signing up for a newsletter? Form. Submitting a job application? Form.
If HTML is the language of the web, forms are the conversation — the part where the user talks back. And if you don't understand how forms work at the HTML level, you'll struggle with everything that comes after: JavaScript form handling, backend processing, validation, and user experience.
This isn't a nice-to-have. Forms are a critical skill. Let's build one from scratch.
The Anatomy of a Form
Every form starts with the <form> element. This is the container that wraps all your inputs, labels, and buttons. It tells the browser: "everything inside here is a form that collects data."
Three things are happening here: the <label> tells the user (and screen readers) what the input is for, the <input> collects the data, and the <button> submits it. The action attribute says where to send the data, and method says how (GET or POST).
That's the skeleton. Now let's meet every piece you can put inside it.
Form Elements — The Building Blocks
HTML gives you eight core form elements. You don't need to memorize them — you need to understand what each one does and when to reach for it.
type attribute.<option> elements. Use when there are multiple predefined choices.<input type="submit"> — it's more flexible.for and id. Clicking it focuses the input.A Real Form Using All Six
We covered this in the accessibility post, but it's worth repeating: every <input> needs a <label>. The for attribute on the label must match the id on the input. This is how screen readers identify what each field is for — and it lets users click the label text to focus the input.
Input Types — The Full Toolkit
The <input> element is the most versatile tag in all of HTML. By changing the type attribute, you completely change what it does. Here are the types you need to know:
Each type gives you built-in browser behavior for free. The email type validates the format automatically. The date type shows a native date picker. The number type adds increment/decrement arrows. You don't need JavaScript for any of this — the browser handles it.
Checkboxes are independent — the user can check as many as they want. Use them for things like "select your interests" or "I agree to the terms."
Radio buttons are exclusive — only one can be selected at a time within the same name group. Use them for "pick one" choices like experience level or payment method.
Form Attributes — The Controls
Attributes are how you configure form behavior. These six are the ones you'll use constantly:
name, the input's value doesn't get submitted at all.<form> tag. The URL where the form data gets sent when submitted.<form> tag. Either GET (data in URL — search queries) or POST (data in body — login, signup).This catches beginners constantly. You build a beautiful form, hit submit, and the data doesn't arrive on the server. Why? Because you forgot the name attribute on your inputs. Without name, the browser doesn't include that field in the submission. It's invisible.
Fieldset + Legend — Grouping Related Inputs
<fieldset> and <legend> are the unsung heroes of form structure. They visually and semantically group related inputs together — which is especially important for accessibility. Screen readers announce the legend as context for every field inside the group.
Just like you use <section> to group related page content, use <fieldset> to group related form fields. The <legend> is like the section heading — it tells users (and screen readers) what the group is about.
GET vs POST — When to Use Which
The method attribute on your form determines how data gets sent:
If the user is reading or searching → GET. If the user is creating, updating, or submitting private data → POST.
I spent an entire afternoon debugging why my contact form wasn't sending data. I checked the JavaScript. I checked the backend. I rewrote the fetch call three times.
The problem? I forgot name attributes on every single input. The form was submitting an empty object. Every field was there visually, but to the server, it was a ghost form. Nothing was coming through.
Now the first thing I check on any form bug: "Do all my inputs have names?" 🫠
🔨 Mini Build: CodeHerWay Signup Form
Build a complete signup form for CodeHerWay with these requirements:
The Bottom Line
Forms are how users communicate with your site. Every login, every signup, every search, every checkout — it all runs through HTML forms. Understanding form elements, input types, and attributes at this level means you'll never be confused when JavaScript and backend code start interacting with them.
Build forms with proper labels. Use the right input types — let the browser work for you. Always include name attributes. Group related fields with <fieldset>. And use required before reaching for JavaScript validation.
This isn't optional knowledge. This is the foundation everything else gets built on.
Post 12: HTML Tables — Tables get a bad reputation because people used to use them for layout. But for actual tabular data? They're the right tool for the job. Next up, we're building tables the right way.