👀 Live Preview
Submit with an empty required field — a custom message appears:

The oninvalid attribute is an inline event handler that runs JavaScript when the invalid event fires — when a form control fails HTML5 constraint validation. That happens when a field breaks rules like required, min, max, pattern, or type="email", usually when the user tries to submit the form. Use it with setCustomValidity() to show friendly error messages, and clear custom validity on oninput so the field can become valid again. Prefer visible inline errors over alert(). Pair with novalidate on the form only if you replace browser validation entirely.
Inline JS.
Validation fail.
Constraints.
Custom message.
Preferred way.
Accessible UX.
oninvalid AttributeThe primary purpose of oninvalid is to respond when a form field does not meet its validation constraints. Instead of a generic browser tooltip, you can set a clear message with setCustomValidity(), highlight the field, or reveal an error paragraph. This makes validation feedback easier to understand — especially for beginners filling out a form for the first time.
The browser runs validation when the user submits a form (unless novalidate is set). If any control is invalid, submission is blocked and the invalid event fires on each invalid field. Your handler runs at that moment — a good place to customize the message or update the UI.
After setCustomValidity("Error message"), reset with setCustomValidity("") in an oninput handler. Otherwise the field stays invalid even after the user fixes it.
Set oninvalid on a validatable form control:
<input type="text" id="username" required
oninvalid="setUsernameError()"
oninput="this.setCustomValidity('')">
<script>
function setUsernameError() {
document.getElementById("username").setCustomValidity(
"Username is required."
);
}
</script>invalid event fires.input, textarea, select.setCustomValidity(message) for custom text; clear with setCustomValidity("").element.oninvalid = function() { … }.element.addEventListener("invalid", handler).invalid event does not bubble in all cases the same way — attach to each field or use capture on the form.The oninvalid attribute accepts a string of JavaScript code:
oninvalid="showError(this)" — Pass the invalid element.oninvalid="this.setCustomValidity('Required')" — Inline custom message.field.oninvalid = () => { … } assigns the handler.const email = document.getElementById("email");
email.addEventListener("invalid", () => {
email.setCustomValidity("Please enter a valid email address.");
});
email.addEventListener("input", () => {
email.setCustomValidity("");
});| Action | invalid fires? | Notes |
|---|---|---|
Submit with empty required field | Yes | Most common trigger |
| Email field with bad format | Yes | type="email" constraint |
checkValidity() returns false | Yes | Programmatic check |
| User types to fix the value | No | Use oninput to clear errors |
Form has novalidate | No | Browser validation disabled |
| Handler attribute | oninvalid | Inline on element |
| Target | Supported? | Notes |
|---|---|---|
<input required> | Yes | Empty value on submit |
<input type="email"> | Yes | Format validation |
<input pattern="..."> | Yes | Regex constraint |
<textarea required> | Yes | Multi-line required |
<select required> | Yes | No option selected |
<button> (no constraints) | No | Not a validated value field |
oninvalid vs oninput vs reportValidity()| API / handler | When it runs | Typical use |
|---|---|---|
oninvalid | Constraint check fails | Custom error message on submit |
oninput | Every value change | Clear setCustomValidity |
checkValidity() | Called in JS | Test validity without UI |
reportValidity() | Called in JS | Show native error bubble |
Required field custom message, addEventListener, and pattern validation with inline errors.
Submit with an empty required field — a custom message appears:
Set a custom message when a required field is empty on submit:
<form>
<label for="username">Username:</label>
<input type="text" id="username" required
oninvalid="this.setCustomValidity('Username is required.')"
oninput="this.setCustomValidity('')">
<input type="submit" value="Submit">
</form>The browser blocks submit and fires invalid on the empty required input. Custom validity sets your message; oninput clears it when the user types.
Attach the handler with addEventListener:
<input type="text" id="dynamicField" required>
<script>
const field = document.getElementById("dynamicField");
field.addEventListener("invalid", function () {
field.setCustomValidity("This field is invalid. Please provide a valid input.");
});
field.addEventListener("input", function () {
field.setCustomValidity("");
});
</script>Register listeners once at page load. Submit or reportValidity() triggers validation and your custom message.
Enforce a password rule with pattern and a friendly oninvalid message:
<input type="password" id="pwd"
pattern=".{8,}" required
oninvalid="this.setCustomValidity('Password must be at least 8 characters.')"
oninput="this.setCustomValidity('')">HTML constraints do the checking; your handler only improves the error message the user sees.
aria-describedby — Point the input at the error message element id.aria-invalid="true" — Set when invalid; remove when the field passes validation.<label>.Click Submit button.
required, pattern, etc.
oninvalid runs.
Custom message, no submit.
The invalid event and oninvalid handler work wherever HTML5 constraint validation is supported — Chrome, Firefox, Safari, Edge, and IE 10+.
oninvalid supportAll major browsers fire invalid on form controls that fail constraint validation.
Bottom line: Use with HTML5 constraints and setCustomValidity for accessible client-side validation.
setCustomValidity() for clear, friendly messagesinput when the user fixes the fieldaria-describedby and aria-invalidaddEventListener("invalid", …) in productionrequired, pattern) with custom messagesalert() in oninvalid — blocks the usersetCustomValidity("") after the user typesnovalidate unless you implement full custom validationoninvalid to elements without validation constraintsThe oninvalid attribute runs JavaScript when a form control fails HTML5 validation — the right hook for custom error messages and accessible inline feedback.
Use setCustomValidity, clear it on input, and prefer addEventListener("invalid", …) over blocking alerts.
oninvalidBookmark these before building validated forms.
invalid fires.
Eventinput, select.
ScopeYour message.
APIReset validity.
PatternNot alert().
A11yinvalid event fires — when a form control fails HTML5 constraint validation.input, textarea, and select with validation constraints like required, pattern, or type="email".setCustomValidity("Your message") in the handler and clear it with setCustomValidity("") on input.checkValidity() / reportValidity() is called.addEventListener("invalid", handler) is preferred for production. Inline oninvalid works for learning.Practice the oninvalid attribute with required-field and pattern examples in the Try It editor.
5 people found this page helpful