The HTML aria-invalid attribute
The aria-invalid attribute flags a field whose value failed validation, with the value true, grammar or spelling. Any other value counts as true, except false, an empty string or undefined. It runs no check and blocks no submission, which leaves the testing to your validation code.
Overview
The aria-invalid attribute reports an entered value that doesn't conform to the format the application expects. Email addresses and telephone numbers are typical cases, and it can also mark an empty required field. Typical form elements can carry it, with or without an ARIA role.
The value true means validation failed, grammar and spelling name a detected error, and false means none was detected. No attribute, an empty string or the word undefined also means false. Browsers must treat any other value as true, so aria-invalid="yes" marks the field invalid.
Its supported roles in WAI-ARIA 1.2 are application, checkbox, combobox, gridcell, listbox, radiogroup, slider, spinbutton, textbox and tree, along with the five roles that inherit it. On other roles, the use is deprecated.
Don't set it on a required widget merely because the user hasn't entered data yet. Wait until after a submit attempt, since the person may still be filling in the field.
On a valid input, aria-invalid="true" leaves validity.valid true and the form submits, since constraint validation ignores it. An empty required input with aria-invalid="false" still blocks the form. With false on a field that fails its pattern, Chrome exposes it as valid and Firefox as invalid.
Syntax
<label for="code">Order code</label>
<input id="code" name="code" value="12" aria-invalid="true">
Values
| Value |
|---|
| false | true | grammar | spelling |
Example
<form id="check">
<label for="code">Order code</label>
<input id="code" placeholder="AB-1234" aria-invalid="false">
<button>Check</button>
<p id="hint" hidden style="color:#b91c1c;margin:8px 0">Use two capitals, a hyphen and four digits.</p>
<p id="out" role="status" style="overflow-wrap:anywhere"></p>
<p>Press Check with the field empty or wrong, then enter AB-1234.</p>
</form>
<script>
const form = document.getElementById('check');
const code = document.getElementById('code');
const hint = document.getElementById('hint');
const out = document.getElementById('out');
form.addEventListener('submit', function (e) {
e.preventDefault();
const good = /^[A-Z]{2}-[0-9]{4}$/.test(code.value.trim());
code.setAttribute('aria-invalid', String(!good));
code.style.outline = good ? '' : '2px solid #b91c1c';
hint.hidden = good;
if (good) code.removeAttribute('aria-errormessage');
else code.setAttribute('aria-errormessage', 'hint');
out.textContent = (good ? 'aria-invalid is false and the hint is hidden and unlinked.' : 'aria-invalid is true and aria-errormessage points at the hint.') +
' validity.valid is ' + code.validity.valid + '.';
});
</script>
Best practices
- Clear
aria-invalidonce the value passes, by setting it to false or removing it. A stale true keeps flagging a field the user has already fixed. - Suggest a fix when you know one, and link the text that holds it with aria-errormessage.
- Treat the attribute as one of three parts, along with styling through
[aria-invalid="true"]and a message linked by aria-errormessage. - Once the user has entered a value, you can check it on blur or wait for submission, though waiting isn't necessarily recommended.
- Reach for it when you write your own validation. HTML's built-in checks show the browser's own message, which varies by browser and can't be styled.























