In each form, is input validation used in a relevant way (except in special cases)?

A screen reader user submits your contact form. Email field missing. The form reloads. Nothing tells them which field is in error, or why. They try again. They fail again. This scenario affects roughly 26% of internet users who rely on assistive technology — and it happens every day because input controls aren't implemented correctly.

This criterion covers three distinct situations: indicating required fields before submission, error messages after invalid submission, and format instructions for fields expecting structured data. For each situation, you need both a visible indication readable by everyone and programmatic markup accessible to assistive technologies.

The baseline rule: aria-required="true" or required to signal obligation, aria-invalid="true" to signal error. These attributes alone aren't enough — they must be paired with a visible indication in the label or in text associated with the field. One without the other fails the test.

The criterion also applies to data formats: a date field expecting DD/MM/YYYY, a phone number with 10 digits, a postal code with 5 digits. These instructions must be visible before validation, not only in the error message afterward.

7 tests to ensure that input errors are reported

Visible indication or required attribute on mandatory fields

  1. Identify all required fields in the form.
  2. For each required field, verify one of these two conditions before any submission:
    • A visible indication (e.g. asterisk, word "required") clearly identifies this specific field;
    • The field has aria-required="true" or the HTML required attribute.
  3. If at least one condition is met for each required field: test passes. If a single required field meets no condition: test fails.

Visible indication of mandatory status in label

  1. Among required fields, isolate those with aria-required="true" or required.
  2. For each, verify that a visible indication of required status appears:
    • In the <label> tag associated with the field;
    • Or in text linked via aria-describedby or aria-labelledby.
  3. If true for all such fields: test passes. A field with aria-required but no visible indication in its label or linked text: test fails.

Identification of field in error or aria-invalid attribute

  1. Trigger an error by submitting the form with a required field empty.
  2. For each error message that appears, verify one of these conditions:
    • The message is visible and explicitly names the field (e.g. "The Email field is required");
    • The associated field has aria-invalid="true".
  3. If one of the two conditions is met for each error message: test passes.

Visible error message in label or associated passage

  1. After invalid submission, identify all fields with aria-invalid="true".
  2. For each, verify the visible error message is:
    • In the <label> tag associated with the field;
    • Or in text linked via aria-describedby.
  3. If one of the two conditions is met for each field in error: test passes. aria-invalid without an error message in the label or linked text: test fails.

Format instruction visible before validation

  1. Identify all fields (required or not) that expect a specific format or data type: date, postal code, phone number, IBAN, etc.
  2. For each field, verify the format instruction is visible before any validation:
    • It names the field if placed outside the label;
    • Or it appears in the <label> tag or in text linked via aria-describedby.
  3. If the instruction is missing or appears only in an error message after submission: test fails.

Field identification or aria-invalid for format errors

  1. After invalid submission, identify error messages that specify an expected format (e.g. "Enter a date in DD/MM/YYYY format").
  2. For each such error message, verify one of the conditions:
    • The message is visible and explicitly names the field;
    • The associated field has aria-invalid="true".
  3. If one of the two conditions is met for each format error message: test passes.

Format instruction in label associated with field aria-invalid

  1. Identify all fields with aria-invalid="true" after invalid submission.
  2. For each, verify a format instruction is visible in:
    • The associated <label> tag;
    • Or in text linked via aria-describedby.
  3. A field with aria-invalid="true" whose format instruction is neither in its <label> nor in linked text: test fails.

Examples

❌ Non-compliant : Required field without accessible indication

<label for="email">Email</label>
<input type="email" id="email" name="email">
 
<!-- After invalid submission -->
<p class="error">This field is required.</p>

Two problems here. First, nothing indicates the field is required before submission — neither visually nor via required or aria-required. Second, the error message doesn't explicitly name the field (which field? there may be ten), and the field lacks aria-invalid="true". A screen reader can't link this message to this field.

✅ Compliant : Required field with format — complete implementation

<label for="date-naissance">
  Date of birth <span aria-hidden="true">*</span>
  <span class="format-hint">(format: DD/MM/YYYY)</span>
</label>
<input
  type="text"
  id="date-naissance"
  name="date-naissance"
  required
  aria-required="true"
  aria-describedby="date-error"
>
<p id="date-error" class="error" hidden>Date of birth is invalid. Use DD/MM/YYYY format (example: 15/06/1990).</p>
 
<!-- After invalid submission, via JavaScript -->
<!-- input.setAttribute('aria-invalid', 'true') -->
<!-- document.getElementById('date-error').hidden = false -->

Before submission: the expected format is visible in the <label>, so it's announced by screen readers on field focus. The required attribute (native) and aria-required="true" (ARIA) signal obligation. After invalid submission: aria-invalid="true" is added dynamically, the error message is made visible and linked via aria-describedby. The message names the field and restates the format. Tests 11.10.1 through 11.10.7 pass.

❌ Non-compliant : Asterisk without legend — common pitfall

<form>
  <label for="nom">Name *</label>
  <input type="text" id="nom" name="nom" required>
 
  <label for="prenom">First name</label>
  <input type="text" id="prenom" name="prenom">
 
  <button type="submit">Send</button>
</form>

The asterisk is visible but its meaning is never explained. A user discovering the form doesn't know * means "required". For screen readers, the asterisk is read as "asterisk", which is pointless since required is already present. Add a global form legend: "Fields marked with a * are required." and hide asterisks from screen readers with aria-hidden="true".

✅ Compliant : Required field indication with global legend

<form>
  <p>Fields marked with a <span aria-hidden="true">*</span><span class="sr-only">asterisk</span> are required.</p>
 
  <label for="nom">
    Name <span aria-hidden="true">*</span>
  </label>
  <input type="text" id="nom" name="nom" required aria-required="true">
 
  <label for="prenom">First name (optional)</label>
  <input type="text" id="prenom" name="prenom">
 
  <button type="submit">Send</button>
</form>

The form-level legend contextualizes the asterisk for all users. The asterisk in the label is hidden from screen readers via aria-hidden="true" because required and aria-required="true" already convey the information. Optional fields are explicitly identified. Tests 11.10.1 and 11.10.2 pass.

Tips and pitfalls

⚠️ aria-invalid="true" set at page load

Classic audit error: the developer hardcodes aria-invalid="true" in initial HTML to "prepare" validation. Result: the field is announced "invalid" as soon as the user lands on it, before they've typed anything. aria-invalid must be added dynamically after a failed submission attempt, never at initial state.

⚠️ Generic error message not linked to field

A block <div class="errors">Please correct the form errors.</div> at page top isn't enough. Test 11.10.3 requires each error message to explicitly name the field — or the field must have aria-invalid="true". A global summary doesn't replace the message-to-field link. Both can coexist, but the individual link is mandatory.

⚠️ Single-field form: tests 11.10.1 and 11.10.2 don't apply

If your form contains only one input field (typically a search bar or newsletter signup field), tests 11.10.1 and 11.10.2 don't apply. The exception also holds if optional fields are explicitly marked as such, visibly, in their <label> or associated legend. Caution: if all form fields are required, these two tests still apply even if optional fields would have been marked.

⚠️ Test 11.10.5: optional fields with format are also covered

Test 11.10.5 isn't only about required fields. A phone number field may be optional but require a specific format (10 digits no spaces). Whenever a format is expected — required or not — the instruction must be visible before submission. Many audits miss this by focusing only on required fields.

💡 Place format in the <label>, not just in placeholder

The placeholder disappears as soon as the user starts typing. It's therefore useless as the sole format indication. Place the instruction in the <label> or in a <p> linked via aria-describedby. The placeholder can remain as a supplementary example, never as the only source of information.

💡 Use aria-describedby to associate error messages

To have the error message announced by screen readers when typing, use aria-describedby pointing to the error message's id. The announced string becomes: "Email, text input, required. Example: [email protected]". With NVDA and JAWS, the message linked via aria-describedby is announced automatically when focus reaches the field in error.

Frequently asked questions

What's the difference between required and aria-required="true" for RGAA form accessibility?

No, both together aren't required by RGAA — one or the other is enough to pass test 11.10.1. In practice, required (native HTML5) triggers the browser's native validation and exposes required status to accessibility. aria-required="true" is useful on custom components that don't support required. On a standard <input>, required alone is sufficient. Some teams add both out of defensive habit — it's not wrong, just benign redundancy.

Why isn't placeholder alone enough to indicate format in an RGAA form?

No, not alone. The placeholder vanishes as soon as the user starts typing, making it useless for those who need to refer to it while typing. It's not reliably announced by all screen readers. RGAA requires the instruction to be visible before validation: a placeholder isn't a persistent visible indication. Use a <p> element or integrate the format into the <label>.

How do I audit RGAA test 11.10.4 for input control in practice?

Submit the form with an invalid value in a field. Inspect the DOM to verify that field received aria-invalid="true". Then find the corresponding error message — it must be either in the field's <label> tag (rare but valid) or in an element linked via aria-describedby. If the error message is displayed in a <div> with no programmatic link to the field, the test fails even if the message is visually nearby.

How do I indicate required input when all fields in an RGAA form are required?

Yes. The exception for single-field forms or explicitly marked optional fields doesn't apply here. When all fields are required, tests 11.10.1 and 11.10.2 still apply. Each field must have aria-required="true" or required, and a visible indication must appear in its label or in linked text.

Why doesn't native HTML5 validation satisfy RGAA criterion 11.10?

Partially. Native validation via required, type="email", pattern, etc. covers tests 11.10.1 and 11.10.3 because it exposes required and invalid status to assistive technology. But native browser error messages are beyond your control: their wording, placement, and accessibility vary by browser. If native presentation poses problems or you want custom messages, disable native validation with novalidate on the <form> and implement your own system with aria-invalid and aria-describedby.

References