Accessible error messages
novalidate turns off the browser's own bubbles so we control the messages; the validity object still does the checking. The message starts with "Error:" so it isn't conveyed by red colour alone.
Every control has an accessible name that the browser computes in a fixed order (aria-labelledby, aria-label, the native label, the content, then title or placeholder); accessible forms pair that with visible labels, required and invalid states, and error messages linked by aria-describedby.
Change the code and press Run (Ctrl+Enter). Predict what will happen first, then break it on purpose and read what changes. Your edits are saved and match the lesson page.
Ready for more? This phase has 6 hands-on exercises with automatic checks.
Practice questions
Write the code in the editor, run it, then open the model answer to compare.
Write an accessible "Choose a plan" group with three radio options (Free, Pro, Team), with Free selected.
Write a phone field with a visible label, a hint "Include your country code", required, and an error message slot, all correctly linked. Show the HTML after a failed submit.
Fix this: <input type="search" placeholder="Search"><button><img src="search.svg"></button>.
Explain it without notes
Walk through how a browser computes the accessible name of a button or input.
Why isn't placeholder text a replacement for a label?
How should a form announce a validation error to a screen reader user?
What is WCAG 2.5.3 Label in Name, and how does aria-label commonly break it?
Preview
Console
Nothing logged yet.Expected console output
invalid: true | focused: true | message: Error: Enter your email address.
invalid: true | focused: true | message: Error: Enter an email like name@example.com.
invalid: false | focused: true | message: (none)