Learning intentions
- I can build an accessible HTML form using label/input pairing correctly.
- I can use HTML5 input types (email, tel, url, number) for appropriate data.
- I can group related fields with
- I can connect a form to Formspree for a real submission.
Success criteria
- My portfolio has a working contact form.
- Every input has a
- At least one input uses an HTML5 type (email, tel, url, or number).
- Related fields are grouped inside
Do Now · 5 min
Fill out a good form and a bad form in your head. What makes one feel right and the other frustrating?
Common form crimes:
- No label (just a placeholder that vanishes when you type)
- Email input that's type="text" (no keyboard optimisation on phones)
- No indication of what's required until you fail to submit
- Tiny touch targets (frustrating on phones)
I Do · ~10 min Teacher demonstration
Step 1 — The form skeleton
<form action="https://formspree.io/f/YOUR_ID" method="POST">
... inputs go here ...
<button type="submit">Send</button>
</form>
action= where the form data gets sentmethod="POST"= standard for submitting new data (GET for search)
Step 2 — Every input needs a label (this is non-negotiable for accessibility)
<!-- PATTERN 1: label + input linked by for/id -->
<label for="email-field">Email address</label>
<input type="email" id="email-field" name="email" required>
<!-- PATTERN 2: label wraps the input (no for/id needed) -->
<label>
Full name
<input type="text" name="name" required>
</label>
Step 3 — HTML5 input types (use the right one!)
type="text" /* generic single-line */
type="email" /* triggers email keyboard on phone, validates @ */
type="tel" /* triggers phone number keyboard on phone */
type="url" /* validates URL format */
type="number" /* numeric only, with up/down arrows */
type="date" /* opens a calendar picker */
type="color" /* opens a colour picker */
type="range" /* slider */
type="password" /* masks input */
type="file" /* file picker */
type="hidden" /* not visible, used for tracking */
Step 4 — Text areas, selects, radios, checkboxes
<!-- Multi-line text -->
<label for="message">Your message</label>
<textarea id="message" name="message" rows="5" required></textarea>
<!-- Dropdown -->
<label for="topic">Topic</label>
<select id="topic" name="topic">
<option value="question">A question</option>
<option value="feedback">Feedback</option>
<option value="work">Work experience</option>
</select>
<!-- Radio (one choice) -->
<fieldset>
<legend>How did you find me?</legend>
<label><input type="radio" name="source" value="google"> Google</label>
<label><input type="radio" name="source" value="friend"> Friend</label>
<label><input type="radio" name="source" value="school"> School</label>
</fieldset>
<!-- Checkbox (multiple choices) -->
<fieldset>
<legend>Interests</legend>
<label><input type="checkbox" name="interests" value="design"> Design</label>
<label><input type="checkbox" name="interests" value="code"> Coding</label>
</fieldset>
Step 5 — Fieldset and legend group related fields
<fieldset> with <legend> tells a screen reader "these fields belong together". The legend is announced before each field in the group.
Step 6 — HTML5 validation (free, built into the browser)
<input type="email" name="email" required>
<input type="text" name="username" required minlength="3" maxlength="20">
<input type="number" name="age" min="13" max="120">
<input type="tel" name="phone" pattern="[0-9]{10}">
<input type="text" name="title" placeholder="e.g. Year 10 student" disabled>
required— can't submit without a valueplaceholder— hint text that vanishes on typing (NOT a replacement for label)disabled— can't interactmin / max / minlength / maxlength / pattern— constraint validation
We Do · ~15 min Guided build
Style the form to match your portfolio:
form { max-width: 500px; margin: 0 auto; }
fieldset { border: 1px solid #e4e7ec; border-radius: 8px; padding: 1rem; margin-bottom: 1rem; }
legend { font-weight: 700; padding: 0 0.5rem; }
label { display: block; font-weight: 600; margin-bottom: 0.3rem; }
input, textarea, select {
width: 100%;
padding: 0.7rem;
border: 2px solid #e4e7ec;
border-radius: 6px;
font: inherit;
}
input:focus, textarea:focus, select:focus {
outline: none;
border-color: #1f3a68;
}
button[type="submit"] {
background: #1f3a68;
color: white;
border: 0;
padding: 0.8rem 1.5rem;
border-radius: 6px;
cursor: pointer;
}
You Do · ~35 min Independent practice
Add a contact section (or contact.html page) to your portfolio:
- Wrap everything in a
<form>with action (Formspree or mailto:). - Include at least: Name (text), Email (type="email"), Message (textarea).
- Every field has a linked
<label>. - Use
<fieldset>+<legend>to group at least one set of related fields. - Use
requiredon at least one field. - Style the form to match your portfolio palette and fonts.
- Test: submit the form; does anything happen?
- Build a proper footer for the page.
Free services for real submissions (no backend needed):
- Formspree.io — free tier (50 submissions/month)
action="mailto:you@school.nsw.edu.au"— simplest fallback (opens email client)
Differentiation
Support
Pre-built form HTML with comments; student swaps in Formspree URL and styles it.
Core
Build from scratch using all 3 semantic grouping elements (label/fieldset/legend).
Extension
Add HTML5 pattern validation with a regex (e.g. phone number pattern). Use :invalid CSS pseudo-class to style fields that fail validation.
Exit Ticket · 5 min
Exit ticket
1. Why does every input need a label?
_______________________________________________________
2. What's the correct input type for each?
Email: _________ Phone: _________ Age: _________
3. Which tag groups related fields? _______
4. Paste the HTML of your favourite input from today's work:
_______________________________________________________
Resources for this lesson
📚 Deeper Reading
External references drawn from Shay Howe's "Learn to Code HTML & CSS" and University of Michigan's "Web Design for Everybody" Coursera specialization. All credit to original authors.
- Shay Howe · Ch 10: Building Forms
Comprehensive form guide — all input types, fieldset/legend, validation attributes. - MDN · Forms and accessibility
Authoritative reference for accessible form design. - Formspree.io (free tier)
Serverless form submission — works for static sites like GitHub Pages.