novalidate: when you take JS control of validation
The default: browser validates
<input required> and friends make the browser block submission and show a tooltip "Please fill out this field." Free, no JS, accessible.
The override: novalidate
<form novalidate> β¦ </form>
Tells the browser: skip native validation entirely. The form submits even if required fields are empty. You then take over via the invalid and submit events.
When you'd actually want this
- You want a unified error UI (your design-system error pill) β the native tooltip clashes with it.
- You're showing errors INLINE under each field instead of one tooltip at a time.
- You want to validate progressively as the user types, not only at submit.
Once you set novalidate, the constraint attributes (required, min, pattern, β¦) are still readable via JS β input.validity.valueMissing, input.validity.patternMismatch. You write the JS that runs those checks and renders your own error UI.
The trap
novalidate only disables the BROWSER's submission block. type="email" still pattern-restricts what the user can type? No β it doesn't. The text-only restriction is the form-control widget (date picker etc), not the required block. So a user can submit "foo" in a type=email field with novalidate.
That means: when you use novalidate, you also lose free server-side trust. Always re-validate on the server too. (You should anyway β see lesson A3-09.)
Sign up to start coding
Theory is open to everyone. The interactive editor, live preview, and check are unlocked with a 7-day free trial β card required, cancel anytime.
Sign up β free trial βFirst 10 lessons in each track are free. No card needed for those.