Day 5 — Forms, inputs and labels
Forms are where your page stops being a document and starts being useful. They are also where accessibility is most often thrown away.
The shape of a form
<form>
<p>
<label for="name">Your name</label><br>
<input type="text" id="name" name="name">
</p>
<p>
<button type="submit">Send</button>
</p>
</form>
- Clicking the label focuses the field - a much bigger tap target on a phone.
- A screen reader announces "Your name, edit text" instead of just "edit text".
id in the box above and the Check tab tells you no label can reach the field. Placeholder text is not a label - it vanishes the moment somebody types.Input types
The type attribute does real work. On a phone it changes the keyboard that comes up, and the browser validates the value for free.
<form>
<p>
<label for="email">Email</label><br>
<input type="email" id="email" name="email" placeholder="you@example.com">
</p>
<p>
<label for="phone">Mobile</label><br>
<input type="tel" id="phone" name="phone" maxlength="10">
</p>
<p>
<label for="fee">Budget</label><br>
<input type="number" id="fee" name="fee" min="0" max="100000" step="500">
</p>
<p>
<label for="start">Preferred start date</label><br>
<input type="date" id="start" name="start">
</p>
<p>
<label for="pw">Password</label><br>
<input type="password" id="pw" name="pw">
</p>
</form>
| type | What you get |
|---|---|
text | Plain text, the default |
email | An @ keyboard, and a format check on submit |
tel | The number pad on a phone |
number | Spinners, plus min, max and step |
date | A date picker |
password | Dots instead of characters |
checkbox | Independent yes or no |
radio | Pick exactly one from a group |
file | A file picker |
hidden | Carried along, never shown |
Required, and free validation
<form>
<p>
<label for="n2">Name</label><br>
<input type="text" id="n2" name="name" required minlength="2">
</p>
<p>
<label for="e2">Email</label><br>
<input type="email" id="e2" name="email" required>
</p>
<p>
<label for="p2">10-digit mobile</label><br>
<input type="tel" id="p2" name="phone" required pattern="[0-9]{10}">
</p>
<p><button type="submit">Book a demo</button></p>
</form>
required out with the developer tools in three seconds, or skip the page entirely and post straight to your server. Always validate again on the server. HTML validation exists to be kind to honest users, not to stop dishonest ones.Choosing from a list
<form>
<p>
<label for="course">Which course?</label><br>
<select id="course" name="course">
<option value="">-- choose --</option>
<option value="excel">Advanced Excel</option>
<option value="powerbi">Power BI</option>
<option value="sql" selected>SQL</option>
</select>
</p>
</form>
value is what gets sent to the server. The text between the tags is what the human reads. They do not have to match.
Radio buttons and checkboxes
Radios in the same group must share the same name. That is what makes them mutually exclusive - not their position on the page.
<form>
<fieldset>
<legend>Batch preference</legend>
<p>
<input type="radio" id="wd" name="batch" value="weekday" checked>
<label for="wd">Weekday</label>
</p>
<p>
<input type="radio" id="we" name="batch" value="weekend">
<label for="we">Weekend</label>
</p>
</fieldset>
<p>
<input type="checkbox" id="terms" name="terms" required>
<label for="terms">I agree to the terms</label>
</p>
</form>
Change the second radio’s name to something else and run it - now both can be selected at once, because they are no longer one group.
<fieldset> and <legend> group related controls and give the group a name a screen reader can announce. Use them for every radio group.
Longer text
<form>
<p>
<label for="goal">What do you want to achieve?</label><br>
<textarea id="goal" name="goal" rows="4" cols="40"></textarea>
</p>
</form>
value attribute - whatever sits between the tags is the starting content. Put a newline in there by accident and it becomes part of the value.Where the form goes
GET puts the values in the URL. Good for a search box, because the result is linkable. POST sends them in the body. Use POST for anything that changes data, and for anything private - a password in a URL ends up in browser history and server logs.
Try these yourself
- Build an enquiry form with name, email, 10-digit mobile and a course dropdown.
- Add a label to every field and check the Check tab is clean.
- Add a radio group for weekday or weekend, wrapped in a fieldset with a legend.
- Make the email required and try submitting the preview with it empty.
- Explain why HTML validation does not remove the need for server-side validation.
