Forms are how users send information through the web. Search boxes, signups, checkouts, login pages, booking flows, and contact pages all depend on HTML forms.
This is one place where correct markup matters immediately. A form can look acceptable and still be confusing, inaccessible, or hard to use if the structure is poor.
The basic form structure
A form groups controls that are submitted together.
<form action="/subscribe" method="post">
<label for="email">Email address</label>
<input type="email" id="email" name="email" />
<button type="submit">Subscribe</button>
</form>
Important parts:
<form>groups the controlsactiontells the browser where to send the datamethodtells it how to send the data- form controls such as
<input>collect user input <button type="submit">submits the form
Even if JavaScript later enhances the form, this HTML foundation still matters.
Labels are essential
Every meaningful form control needs a label.
<label for="name">Full name</label>
<input type="text" id="name" name="name" />
The for attribute on the label matches the input’s id. That association helps:
- screen reader users
- people using voice input
- users who click the label text to focus the field
- anyone trying to understand the form quickly
Do not rely on placeholder text as the label.
Bad pattern:
<input type="email" placeholder="Email address" />
Placeholders disappear as the user types and are not a full replacement for labels.
name matters for submission
An input’s id helps label it. Its name identifies the field in submitted form data.
<input type="email" id="email" name="email" />
Without name, the control usually will not be included in the submitted data.
This is a common beginner mistake.
Common input types
Use input types that match the kind of data you want:
textfor general short textemailfor email addressespasswordfor passwordstelfor phone numbersnumberfor numeric inputdatefor datescheckboxfor independent on/off choicesradiofor choosing one option from a setfilefor uploads
Example:
<label for="guests">Number of guests</label>
<input type="number" id="guests" name="guests" min="1" max="12" />
The input type helps browsers offer better keyboards, validation, and interaction patterns.
Textareas and select menus
Use <textarea> for multi-line text:
<label for="notes">Dietary notes</label>
<textarea id="notes" name="notes"></textarea>
Use <select> when the user should choose from a known set of options:
<label for="class-level">Class level</label>
<select id="class-level" name="classLevel">
<option value="">Choose a level</option>
<option value="beginner">Beginner</option>
<option value="intermediate">Intermediate</option>
</select>
Do not use a select menu when free text would be more appropriate. Match the control to the task.
Group related controls with fieldset and legend
When several controls belong to one question, group them with <fieldset> and label the group with <legend>.
<fieldset>
<legend>Preferred pickup day</legend>
<label>
<input type="radio" name="pickupDay" value="friday" />
Friday
</label>
<label>
<input type="radio" name="pickupDay" value="saturday" />
Saturday
</label>
</fieldset>
This is especially important for radio buttons and related checkboxes.
Buttons
Use <button> for actions inside forms.
<button type="submit">Send request</button>
<button type="reset">Clear form</button>
<button type="button">Show price estimate</button>
Common button types:
submitsubmits the formresetresets the controls to their initial valuesbuttondoes nothing by default and is useful when JavaScript adds behavior later
Inside forms, being explicit about type is a good habit.
Basic built-in validation
HTML provides useful validation features without JavaScript:
<input
type="email"
id="email"
name="email"
required
autocomplete="email"
/>
Helpful attributes include:
requiredminlengthmaxlengthminmaxpatternautocomplete
These do not replace all validation, especially server-side validation, but they improve the default experience.
A realistic form example
<form action="/classes/register" method="post">
<h2>Register for a class</h2>
<p>
<label for="full-name">Full name</label>
<input
type="text"
id="full-name"
name="fullName"
required
autocomplete="name"
/>
</p>
<p>
<label for="email">Email address</label>
<input
type="email"
id="email"
name="email"
required
autocomplete="email"
/>
</p>
<p>
<label for="class-level">Class level</label>
<select id="class-level" name="classLevel" required>
<option value="">Choose a level</option>
<option value="beginner">Beginner</option>
<option value="intermediate">Intermediate</option>
</select>
</p>
<fieldset>
<legend>Preferred session</legend>
<label>
<input type="radio" name="session" value="morning" required />
Morning
</label>
<label>
<input type="radio" name="session" value="afternoon" />
Afternoon
</label>
</fieldset>
<p>
<label for="notes">Dietary notes or accessibility needs</label>
<textarea id="notes" name="notes"></textarea>
</p>
<p>
<label>
<input type="checkbox" name="updates" value="yes" />
Send me future class updates
</label>
</p>
<button type="submit">Register</button>
</form>
This form is still plain HTML, but it already supports a useful real task.
Default browser behavior is a feature
One helpful mental model: forms work without JavaScript.
By default, the browser:
- tracks field values
- supports keyboard navigation
- associates labels
- runs built-in validation rules
- submits data to the URL in
action
JavaScript can improve forms later, but it should usually enhance this base rather than replace it carelessly.
What to carry forward
- forms group controls that submit data together
- labels are essential and should be properly associated with inputs
namematters for submitted data- use input types that match the kind of information you want
<textarea>,<select>,<fieldset>, and<legend>solve common real-world form needs- button types should be explicit inside forms
- built-in HTML validation and autocomplete improve usability
- a good form should make sense and work before JavaScript is added
The next lesson covers tables: how to mark up structured data when rows and columns really are the right model.