Forms Project
title: "Forms Project — Build a Complete Accessible Registration Form" description: "Build a production-ready accessible registration form applying all form accessibility patterns including labels, errors, focus management, and live regions." weight: 15 date: 2026-06-28 lastmod: 2026-06-28 tags: [accessibility, forms]
Apply everything you learned by building a complete accessible multi-step registration form with validation, error handling, and success confirmation.
## What You'll Learn
How to combine labels, ARIA, validation, focus management, and live regions into a single production-ready form.
## Why It Matters
A complete registration form is the most common form type on the web. Mastering it ensures users can sign up for your service without barriers.
## Real-World Use
A user registers for a DodaTech account. The form asks for email, password, and profile details across two steps, with inline validation, clear error messages, and a success confirmation that the screen reader announces.
## The Complete Form
```html
<form id="registration" novalidate aria-label="User registration">
<div role="alert" id="form-errors" aria-live="assertive"></div>
<fieldset>
<legend>Account credentials</legend>
<label for="reg-email">Email address</label>
<input type="email" id="reg-email" name="email" required
autocomplete="email"
aria-describedby="reg-email-hint reg-email-error"
aria-invalid="false">
<p id="reg-email-hint">We will send a confirmation email</p>
<p id="reg-email-error" role="alert"></p>
<label for="reg-password">Password</label>
<input type="password" id="reg-password" name="password" required
minlength="8" autocomplete="new-password"
aria-describedby="reg-password-rules reg-password-error"
aria-invalid="false">
<ul id="reg-password-rules">
<li>At least 8 characters</li>
<li>One uppercase letter</li>
<li>One number</li>
</ul>
<p id="reg-password-error" role="alert"></p>
</fieldset>
<button type="submit">Create account</button>
</form>
<div id="success-message" role="status" aria-live="polite" hidden>
<h2 tabindex="-1">Account created successfully</h2>
<p>Check your email to verify your account.</p>
</div>
JavaScript Validation
document.getElementById('registration').addEventListener('submit', async function(e) {
e.preventDefault();
let hasError = false;
const fields = this.querySelectorAll('[aria-invalid]');
fields.forEach(field => {
const errorEl = document.getElementById(field.getAttribute('aria-describedby').split(' ').pop());
if (!field.validity.valid) {
field.setAttribute('aria-invalid', 'true');
errorEl.textContent = field.validationMessage;
hasError = true;
} else {
field.setAttribute('aria-invalid', 'false');
errorEl.textContent = '';
}
});
if (hasError) {
const firstError = this.querySelector('[aria-invalid="true"]');
firstError.focus();
return;
}
const form = this;
form.hidden = true;
const success = document.getElementById('success-message');
success.hidden = false;
success.querySelector('h2').focus();
});
Common Mistakes
1. Skipping form-level error summary
Always provide a summary at the top for screen readers to get an overview of all errors.
2. No validation on required fields before submission
Client-side validation prevents unnecessary server round-trips but must not bypass server validation.
3. Forgetting autocomplete on all fields
Every field that collects personal data needs an appropriate autocomplete attribute.
4. Not hiding the form after success
Leaving the form visible after submission risks double-submission and confusion.
5. No server-side validation fallback
Client-side validation is for UX, not security. Always validate on the server.
Practice Questions
1. What should happen after successful form submission? The form should hide, a success message should appear, and focus should move to the success message heading.
2. Why is novalidate used on the form element? novalidate disables browser-native validation so we can provide accessible custom error messages.
3. What is the purpose of the form-level error summary div? It provides an overview of all errors for screen reader users and sighted users scanning the form.
Challenge: Extend the registration form to include a multi-step profile section (name, address, preferences) with proper focus management between steps.
FAQ
Mini Project
Build the complete registration form and deploy it. Then create a second form of your choice (contact form, checkout form, survey form) applying all the patterns from this tutorial series.
What's Next
Now explore Accessible Navigation to learn how to build navigation systems that all users can operate.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro